Calling API after region change : doesn't work every time

Hi,


I'm struggling to develop a feature for an iPhone app:

1. User enter/leave a region

2. An endPoint is called


When app is relaunched by the system because of the region change, sometime the endPoint is called right away, sometimes after 2hours, sometimes never...

It seems that this issue started from iOS13.


I tried to stick as much as possible to Apple guidelines :

API is called from background (because app is in background state when relaunched by location update):


let configuration = URLSessionConfiguration.background(withIdentifier: identifier)
configuration.sessionSendsLaunchEvents = true
configuration.networkServiceType = .responsiveData
configuration.sharedContainerIdentifier = "***.***.***"
configuration.requestCachePolicy = .reloadIgnoringCacheData
configuration.shouldUseExtendedBackgroundIdleMode = true
let session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)



I download the response instead of getting it:

urlSession.downloadTask(with: request)


I handle events for background URLSession

application(_ application : UIApplication, handleEventsForBackgroundURLSession identifier : String, completionHandler : @escaping () -> ())

App has got the following capability:

- Background Fetch


It works perfectly on the simulator.

On a real device it works about 75% of time.


I've also tried UIApplication.beginBackgroundTask but with no success.


So, my questions are:

- how can I have a 100% success endPoint call when region is changed (and network is available)?

- Am I using the right methods? Do I missed something?

- Is there a way to test it with the debugger? The issue I'm experiencing is only when app is closed and a region change event is triggered. The solution I found is to develop a small logging library that writes each events locally, so I can read them when I relaunch the app manually. It's not really handy to debug.


Thanks for your answers 🙂

NSURLSession
background sessions are intended to be use for large, non-interactive work. The tradeoff here is that that they offer no latency guarantees: When you run a request in a background session, the system is free to schedule that request at its convenience. It’s not uncommon for such requests to be delayed until the evening, when the phone is plugged in to mains power and connected to the user’s home Wi-Fi.

If latency is important to you, it’s best to stick with a standard session, using a

UIApplication
background task to prevent your app from suspending while your request is in flight. The drawback here is that, in poor network conditions, your
UIApplication
background task might expire before your network request completes. You have to decide what to do in that case, but one option is to cancel the task in the standard session and create a new task in a background session.

For more info about

UIApplication
background tasks, see my UIApplication Background Task Notes post.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you for your reply.


If I understand well, the steps are:

1. UIApplication.beginBackgroundTask

2. If expired -> URLSessionConfiguration.background(withIdentifier: identifier)


One more thing : have you any trick to test the background modes?

As the app is waken up by the location change, so not launched by Xcode, how to debug it (have breakpoint)?


Is the simulator working exactly as a real device on background modes? Is there some differences?


Thanks!

Is the simulator working exactly as a real device on background modes?

Not even close! You must test background code on a real device.

have you any trick to test the background modes?

Not in the way that you’re hoping for )-: but a lot of the advice from Testing Background Session Code applies here as well.

If I understand well, the steps are:

I’m sorry but that summary is too brief for me to tell whether you’re on the right track.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Calling API after region change : doesn't work every time
 
 
Q