NOTE: This article is about allowing your iOS app to run when it goes into the background (i.e. another app becomes active) for a short period (up to 3 minutes on iOS 9, at least). It does not relate to having the UIBackgroundModes option, an example of which is here.
As some of you will already know, some methods on iOS classes which have been “imported” into Delphi, have been left out, for whatever reason that might be, and some are quite unfortunate, because it means having to work around it, as per the example I linked to, above.
This is the case for UIApplication, where two methods related to enabling an iOS app to run when the app is in the background, have been left out; namely:
function beginBackgroundTaskWithExpirationHandler(handler: TBackgroundTaskHandler): UIBackgroundTaskIdentifier; cdecl; procedure endBackgroundTask(identifier: UIBackgroundTaskIdentifier); cdecl;
I knew of this omission a while ago, and a recent post on Google+ prompted me to look into it in more depth. The two methods seemed easy enough to use, so I put together a class that wraps the 2 calls and makes using them a bit more convenient. The result is in the demo that follows at the end of this article. Rather than going too deep into explanations, I’ll allow the reader to have a look at it, and I’ll field questions if necessary 🙂
Hi,
if i want make app run at background without expire time,
how if i make command at OnExpiry as comment ‘{}’ it will work?
regards,
Anang
Hi Anang,
It depends on what your app is going to do in the background. iOS allows only certain things to happen in the background, as per my blog post, here:
http://blog.delphiworlds.com/2013/10/providing-background-services-support-to-your-ios-apps-with-delphi/
(The link to the Apple Reference no longer works. Something for me to fix)
If you give an idea of what your application is going to be doing in the background (as long as it is an activity that is allowed by iOS), I might be able to help.
Hi,
i working on beacon, i’ve add UIBackgroundModes fetch & bluetooth, for working in backgroundmode i use BackgroundTaskManager.pas, then i follow you suggestion for modified System.IOS.Beacon.pas on TiOSBeaconManager.DoStartScan
add LBeaconIdentifier.GetRegion.setNotifyEntryStateOnDisplay(True), before the FLocationManager.startMonitoringForRegion call.
app working well on background, when beacon proximity it show notification, but after couple minute it’s not work/stop, but when i make app foreground, then app working again in foreground or background mode then stop again after couple minute so on, so on…
another condition app stop working when i lock screen.
my question , can BackgroundTaskManager.pas handle that condition?
should i Disable the Idle Timer on iOS using the ObjectiveC Bridge when background mode
UIApp.setIdleTimerDisabled(True)
then UIApp.setIdleTimerDisabled(False) when becameactive
regards,
anang
If you’re following all of my suggested changes, then I don’t know why it doesn’t continue to work in the background. The main points are:
Ensure the “location” value is in UIBackgroundModes in the Version Info section of Project Options.
Ensure that the LocationChange value of the TLocationSensor is lctLarge *before* the app actually goes into the background (use the WillBecomeInactive application event)
Ensure that requestAlwaysAuthorization is called (as per my example)
Ensure that setAllowsBackgroundLocationUpdates(True) is called. Note that this function seems to crash on 32-bit iOS, so make sure you compile for 64-bit
I’m working on a “bare bones” demo based around the MonkeyFence demo that’s in this article:
http://blog.delphiworlds.com/2016/07/region-monitoring-background-ios/
That will cover the basics, and I’ll be posting that later.
many thanks for relpy,
i have read about time expire when app in background mode, maximum 10 minute,
but BackgroundTaskManager demo will expire 3 minute, how to make expire time to 10 minute?
regards,
Anang
iOS no longer has the 10 minute maximum; they changed that in iOS 7.
You cannot change the 3 minute maximum; that is set by iOS itself.
I have a Delphi FMX application for iOS where I need it to remain running in the background. My application communicates with a server, and returns some strings that will be used for notification. And I need to query this server every 3 minutes and transform the return string into a local notification. Does anyone have any ideas?
I’ve commented on your question on Stack Overflow: https://stackoverflow.com/q/77640045