Infinite background execution on iPhone - ios

I'm developing iOS application that should do some background work with specific interval (30-3600 seconds) so ideally I'm need infinite background execution for my app. I'm using "update 1" solution from this answer but there is one problem.
I'm using setKeepAliveTimeout:600 handler: to register keep-alive handler in application: didFinishLaunchingWithOptions: delegate method and;
Calling beginBackgroundTaskWithExpirationHandler:;
Moving app to background. Everything is fine. Timers are firing, work in progress, backgroundTimeRemaining says i have ~600 seconds;
After 600 second app is suspended;
After few seconds keep-alive handler calling and requesting background execution again. But this time backgroundTimeRemaining says i only have about 50 seconds;
After 50 seconds the application is suspended again;
~550 seconds suspend;
GOTO 5.
I'm testing my app on iPhone 3GS with latest version OS (6.1.3).
So the question is why I'm getting only about 50 seconds after second time call for beginBackgroundTaskWithExpirationHandler:?
Is there any other way to do some work with short-time interval (e.g. 30 seconds) in background on iOS?
PS: Application I'm developing is for in-company usage, so I don't care about rejecting it by Apple.

Related

Linphone iOS App crash during outgoing call, BackgroundTask

I build my own SIP app based on Linphone SDK.
When I make an outgoing call, then after 30 seconds of the call I get these messages:
[BackgroundTask] Background Task 7 ("Liblinphone cpu lock"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.
[BackgroundTask] Background Task 10 ("belle-sip transaction(0x280e88410)"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.
Then the App crash after 30 seconds or sometimes after up to max 4 minutes of having an outgoing call active. This crash also happens if my app is only ringing for more then 30 seconds when I try to make an outgoing call.
When the crash happens, then the app is NOT in background. The app is just in foreground during an outgoing all.
The app is build with Swift 5.0 and iOS target version 13.0

What happens when app returns to foreground after 30 seconds of background execution finished?

If an application starts to perform some activity in the foreground, then it moves to the background and continues to execute for the 30 seconds that the OS lets it run for, but then within that 30 seconds it has not completed what it was doing.
Then what happens when the app next comes to the foreground? Does whatever processing it was in the middle of doing when the 30 seconds was up automatically get resumed at the point it got suspended by the OS when in the background and the 30 seconds finished?
(Similar question - suppose the app calls UIApplication.setMinimumBackgroundFetchInterval().
Then if the user moves the app to the background, it runs for 30 seconds then stops, then the OS runs it in the background due to setMinimumBackgroundFetchInterval having been called, does it resume exactly what it was doing at the end of the 30 seconds?)
No, it does not continue. It seems that the answers you are looking for can be found in this parts of the documentation (emphasis mine), depending on how you transfer tasks to the background :
https://developer.apple.com/documentation/uikit/uiapplication/1623051-beginbackgroundtask
Each call to this method must be balanced by a matching call to the endBackgroundTask(_:) method. Apps running background tasks have a finite amount of time in which to run them. (You can find out how much time is available using the backgroundTimeRemaining property.) If you do not call endBackgroundTask(_:) for each task before time expires, the system kills the app. If you provide a block object in the handler parameter, the system calls your handler before time expires to give you a chance to end the task.
https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623125-application
When this method is called, your app has up to 30 seconds of wall-clock time to perform the download operation and call the specified completion handler block. In practice, your app should call the completion handler block as soon as possible after downloading the needed data. If you do not call the completion handler in time, your app is terminated.

How to keep running iOS application (iOS 9+) in background till user changes wifi settings of iOS device

In my application, the user needs to connect the device wifi to another wifi via the iOS settings. I want my app to remain in the background for some time(like 5 min max) without getting suspended, until the user connects to the other network and returns to the application.
I observe that my application gets removed from background during switching the device wifi. The application doesn't remain active in the background.
How do I keep the iOS application (iOS 9+) in background for some time i.e 5 min?
Apps moving to the background are expected to put themselves into a
quiescent state as quickly as possible so that they can be suspended
by the system. If your app is in the middle of a task and needs a
little extra time to complete that task, it can call the
beginBackgroundTaskWithName:expirationHandler: or
beginBackgroundTaskWithExpirationHandler: method of the UIApplication
object to request some additional execution time. Calling either of
these methods delays the suspension of your app temporarily, giving it
a little extra time to finish its work. Upon completion of that work,
your app must call the endBackgroundTask: method to let the system
know that it is finished and can be suspended.
(source: https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html)
Read iOS Backgrounding with Tasks .
The time App will be in background in 10 minutes that is 600 seconds.
You can know time remaining using the code
NSLog(#"Time Remaining: %f", [[UIApplication sharedApplication] backgroundTimeRemaining]);
Since your need is just turning wifi on- It may take less than 10 minutes i think.
Hope my answer is Clear and Helpful.

Before iOS7 was it possible to execute background task if it didnt involve audio, location etc

Apple has provided certain services which can run in the background for 10 minutes, but what if I have to perform some other task like downloading a file ... how much time limit do I get for it
Before iOS 7 you could request up to 10 minutes of background time (via beginBackgroundTaskWithExpirationHandler:) or you could use any of the background modes available at the time (such as location, voip, etc).
VoIP handler, for instance, will be called at most every 10 minutes and will give up to 3 minutes of background time IIRC.
With iOS 7 you can download and upload files out-of-process, without your app running. Please check documentation on NSURLSession and NSURLSessionConfiguration.
You can do it (directly after your app went to the background, that is, not let's say an hour later), and you approx. do have 10 minutes, although that is not guaranteed. See here in the apple documentation:
https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW20
You can request a Executing a Finite-Length Task in the Background
which will run in background for maximum 10 min. This should be long enough to download file.
So no it is not just for certain services, you can get your app running the background for a longer period of time if your app is a VOIP app, track user location, playing audio or your app is app for an external accessories.

When waking up from significant location change notification how much time do I have in the background?

Testing an app that monitors a region then wakes up to do some processing. I cant seem to find anywhere documentation that says how long I have to do work in the background before the watchdog timer kicks in and kills the app.
I saw a document (even I believe official one) where most of the timings related to background was shown. However, I can't find it right now (I will try to find it and post here).
Based on my experience, I believe application is awoken for 10 seconds while significant location change. Also, the interesting thing that if you try to do call backgroundTimeRemaining it will return +INFINITY for these 10 seconds (generally speaking this API is designed only for beginBackgroundTaskWithExpirationHandler:)
Update 1
Sorry. I wasn't able to find that document. I have a feeling that it was remove/updated by Apple, because before (about 6 month ago) I hit it quite often while searching information on iOS backgrounding.
I found couple of interesting things. One is here. It's related to VOIP callback.
It says: "Your handler has a maximum of 10 seconds to perform any needed tasks and exit. If it does not exit before time expires, the application is suspended."
Also, the same 10 seconds are mentioned here for Bluetooth:
"Upon being woken up, the app has around 10 seconds to process the data."
I believe underlying mechanics for location manager wake up, VOIP and Bluetooth wake up are exactly the same and all of them grant 10 seconds of execution time/
you can register for a maximum of 10 minutes background-task.
But if you want to know, how long the called method can be executed, try measuring it with a infinite while-loop!

Resources