I have an iOS app that use the location services.
I need to call StartUpdatingLocation() while the app is in the background at a specific time (ie 4/17/2014 at 3:00 pm).
Previously I tried using a timer to do this, but found out that you can't run a timer while the app is in the background on iOS 7. Currently I'm running the location services when the app is initially booted and slowly updating it every so often. With each update, I check if the specific start time has been reached yet and if so I start logging the coordinates to the database.
Is there a more efficient/less data and battery intensive way to have location services start from the background of an iOS 7 application?
I've also considered using LocationUpdatesPaused and LocationUpdatesResumed events to help reduce the battery and data usage, while checking for my specific date and time.
I've consulted this helpful link: http://gooddevbaddev.wordpress.com/2013/10/22/ios-7-running-location-based-apps-in-the-background/
You can't do this.
Apple explicitly state in their documentation you should not call StartUpdatingLocation() while in the background.
Apparently you used to be able to do this and it worked before iOS7 but I tried it with iOS7 and it doesn't work, so if it used to be possible it now no longer is.
But apart from that, with iOS there is no way of scheduling an action at a particular time in the background to occur anyway.
What you could do is change the accuracy to low (in combination with pausing updates etc.) when you don't need location updates and set it to high when you do to preserve battery life, but you cannot do this at a specific time when in the background.
iOS supports background location services as long as you declare them in your info.plist file like so:
...
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
...
However, Apple is very fussy about the types of app it will approve with this behaviour because of battery life implications.
Related
My app (made with Flutter but this should not matter) has something like a timer functionality that makes a tick sound in regular periods (between 10s and 3min). I have the background mode Audio, AirPlay, and Picture in Picture activated and the following in my Info.plist.
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
but the audio will still stop when running in background.
This occurs when running the app in profile mode, when I run in debug mode, the audio continues when running in background.
What can I do to have the audio continue to run in background?
There is a relevant note in the audio_service 0.18.0 README which can help here:
Note that the audio background mode permits an app to run in the background only for the purpose of playing audio. The OS may kill your process if it sits idly without playing audio, for example, by using a timer to sleep for a few seconds. If your app needs to pause for a few seconds between audio tracks, consider playing a silent audio track to create that effect rather than using an idle timer.
Well, unless you did this in native code (Swift/Objective-C), your code is running inside the Flutter engine - probably with some Dart Timer.periodic.
The Flutter engine may be killed off at any point in time when the app is in the background. On Android this can even happen when simply switching to the camera and back to the app afterwards. On iOS usually after some fixed time or on high system load.
In this regard, Flutter (and most other cross-platform toolkits) are very different to native apps.
You can start with the official documentation here: https://flutter.dev/docs/development/packages-and-plugins/background-processes
This may be a good article: https://medium.com/vrt-digital-studio/flutter-workmanager-81e0cfbd6f6e
I don't know enough about iOS but I think there is no easy way to schedule execution in the small intervals you require. On Android something like the AlarmManager can be used.
You can try writing the scheduling code natively and schedule it from the app via a MethodChannel when the period is set.
You can look at these libraries:
https://pub.dev/packages/workmanager (probably can't wake up at the small intervals you need)
https://pub.dev/packages/android_alarm_manager_plus (only for Android)
https://pub.dev/packages/audio_service (may give you some idea on how to achieve background execution on iOS)
Edit:
After reading more about Enabling Background Audio on iOS, it seems to me, that this only works when using
an AVAudioSession. Which you are probably not using. To get this working you need some native code. The audio_service package uses such a session. You can try scheduling with Dart code and playing the sound via the audio_service package. Sounds like it could work but I have no experience with this package.
Please, pay attention to the answer from #RyanHeise – he's correct on the point of using AudioSession: in background you should play either sound or silence. As soon as audio will be paused, app can be suspended.
Also, Important Note: when app entering background, scheduled timers will pause. That's why you might think it stopped working. Do not use scheduling via Timers on background - rely on events from the system.
i have a big problem. I am working on an app about accessibility. The app should work through the iPhone microphone to take over sounds from the environment (indoor) and compare them in real time with sounds in the app database (recorded from users previously). If sounds match, the user will be warned by the app through a notification. So... firstly, the app should listen sounds working in background, but after some minutes, iOS closes the app in background automatically. IS THERE SOME SOLUTIONS FOR THIS PROBLEM? TO ALLOW THE APP BE OPENED AND WORKING?
Secondly, do you know in which way is possible compare sounds recorded with sounds listened by microphone in real time?
Really really thank you. 🙏🏻
Regarding the problem that your app is automatically closed, it seems that something was not configured properly in your project.
When the UIBackgroundModes key contains the audio value, the system’s
media frameworks automatically prevent the corresponding app from
being suspended when it moves to the background.
Make sure that you have enabled the "Audio, AirPlay and Picture in Picture" background mode in your project.
Fore the first question:
Because your app will be recording the audio while in background, you can:
set UIBackgroundModes key in your app’s Info.plist file to audio.
It should keep your app alive when you press Home button. See the Declaring Your App’s Supported Background Tasks section
At some point, iOS can kill your app due to some conditions, but
eventually it would restart your app later.
And be careful with this, you might have to deal with Apple Review team to prove that your app is not doing something harm to user privacy. Otherwise, they wouldn't let it go live.
For the second question:
I think you can use some AI/Machine Learning service out there to do so. It's much more accurate and faster than building it your own.
I have a Timer which plays AVAudio at a specific time while the screen is locked (app in foreground when locked and plist setting 'Application does not run in background' set to YES).
When I run my code while my iPhone is connected to Xcode it works as desired, playing audio while locked even when the iPhone has been locked for hours.
Now if I disconnect my iPhone and just open the app by tapping the icon the audio won't be played if it's set for more than a minute.
Is there a difference that causes this problem? If I would publish my App to the AppStore which behaviour would my users get?
That 'Application does not run in background' flag is a very old flag that means your app does not support multitasking and should be terminated when the user presses the home button. There's no good reason I can think of to set that flag on a newly developed application. Unless you understand exactly what it's for and are positive that setting it to yes is the correct thing to do, don't do that.
(That flag was added when iOS 4 was released, to allow apps that could not handle multi-tasking to request the old terminate-on-home-button behavior from iOS 3. Given that we're now 6 major iOS releases from iOS 4, it seems outdated.)
So remove that flag. It probably doesn't have any impact on your question, but remove it or set it to no in any case.
If you want to run a timer while the phone is locked and play sounds at designated times then you will probably need to set your app up as a background sound player, and ask for more background time when you get a message that you are going to the background.
That being said it's likely that Apple will reject your app. Running a timer from the background means that the processor on the phone has to run at full speed all the time, which will DRAMATICALLY reduce battery life.
Apple only allows a very small subset of apps to run in the background, and then only under specific circumstances (like a background sound playing app when the user is actively listening to music, or a navigation app that is actively tracking the user's location and notifying them when it's time to make a turn to follow directions.)
Should be no different. If you'd like to feel what do your users' feel then you can publish it to TestFlight which is the best app beta test environment. Find some testers or try it yourself.
The directions should be to verify the playing logic and the sound file relationship which link to the connection.
I'm working on a cordova application which needs to get location updates and send them to a server even if the device is in sleep mode. I can track the location of a device if the app is on foreground and also background with my version now. But after 10-15 minutes the app gets killed by OS and I no longer get any location updates until the user launches my app again.
Well in my search of finding a solution to this problem I found this article:
http://mobileoop.com/getting-location-updates-for-ios-7-and-8-when-the-app-is-killedterminatedsuspended
It shows how to get location updates even if the app gets killed. The main problem is that I'm not really sure that this could work with a non-jailbreaked iOS and I've never wrote a cordova plugin myself before.
So is it possible to track location and send those through socket.io or http to a specific server?
Or at least to write those geolocation updates in files which I would send when my app launched?
If the answer of my first question is yes: How should the plugin look like?
#Kingalione,
you can keep the App from being killed. There was a documentation error in Apple's documentation. Here is my blog post on this:
Slight Documentation Error causes Background Operations Issuehttp://codesnippets.altervista.org/blog/2015/BLOG.2015-07-02.jssnippets.html
To apply this fix, you'll need to add to your .plist file. Unfortunately, I do not know how to do this for the Cordova CLI. Here is the section that you need for UIBackgroundModes
I'm building an activity analyzer application for iPhone and I use iOS 7. In order to do these i use CMMotionManager and I access accelerometer data.After this I write the datum to database. My application has to work also in background and I used queues, GCD, blocks and other such things in my code to do this properly. Problem is, all of these are working properly when iPhone is plugged in with Xcode but if I run the app without Xcode, app runs about 4 or 5 minutes.After, it is terminated.What is the reason for this?
iOS apps can only run in background, if they fit in one of apples defined background modes such as "App registers for location updates","App provides Voice over IP services","App plays audio","App processes Newsstand Kit downloads","App communicates using CoreBluetooth"",App shares data using CoreBluetooth" and a few more. All background modes you will find in xcode in the capabilities section auf your project(click on project name upper left->mainwindow->second tab).
if your app fits into one of these modes, you must enable this in your app.plist by setting the checkbox in the capabilities section.
if your app doesn't fit in any of these modes you can run in background only a limited amount of time and then iOS stops all activities.
For testing you could start any background mode. but when your app shall be reviewed for deploying via app store apple will reject the app if you use the background mode without legitimation.
The reason for this is that iOS 7 (actually all versions of iOS) will suspend a background task, and potentially terminate it if it's misbehaving, only certain kinds of apps can keep running. Here is the apple doc on it: https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW20
So, given your situation, you'd most likely have to "lie" about what type of app your app actually is, which will get you rejected from the app store.
If you do decide to go the route of a hack, be very careful about battery life, cpu usage, and memory usage, as there is a reason apple did this.
FYI: The "type" is set in your Info.plist file.