Best practice for background synchronization with authorization

I am currently programming an app that should work offline. The data should be synchronized periodically in the background. Most of the data only needs to be loaded from the server. A few also need to be sent to the server.

My first thought for synchronization was to use the BackgroundTask framework. So to use several BGAppRefreshTaskRequest for the synchronization. Several, because the data is refreshed with different frequency.

Since the normal background URLSession does not work when the request is started via a Background Task the request has to be executed via a Background URLSession. Is this correct? I've found different information about this, so sometimes it's said that normal requests without a background session also work.

The main problem with the application is that the user authenticates via OAuth and the token is only valid for one hour. After that, the token has to be renewed. Is this possible with the Background URLSession? My idea now was to check for a 401 error on the DownloadTask and then initialize a token refresh, once successful retry the original request. This would all run through the Background URLSession. However, since the system schedules and executes the requests I wonder if this would even work in this constellation.

Maybe there are other ways to implement synchronization. What would be the best approach here?

Thanks,
Lars
Answered by DTS Engineer in 668208022

Since the normal background URLSession does not work when the
request is started via a Background Task the request has to be
executed via a Background URLSession. Is this correct?

No. A standard URLSession can work from the background you just have to ensure that the app isn’t suspended while that work is in progress. That may not be possible in the general case but in some cases it’s both possible and useful. For example a BGAppRefreshTaskRequest gives your app some execution time in the background and you can use that to run a network request if you like. Your app will remain running in the background until either you complete the network request (by calling task.setTaskCompleted(success:) on the task) or you run out of background execution time (the task calls your expirationHandler).

For more background (hey hey) on this, see my UIApplication Background Task Notes post. This is cast in terms of the older API but the same basic logic applies.

Having said that, whether this is the right choice depends on a lot of things, the most critical being the size and latency requirements of your transfers.

The main problem with the application is that the user authenticates
via OAuth and the token is only valid for one hour.

This is what urlSession(_:task:willBeginDelayedRequest:completionHandler:) is for.

Again, whether this makes sense in your context depends on the exact details.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Accepted Answer

Since the normal background URLSession does not work when the
request is started via a Background Task the request has to be
executed via a Background URLSession. Is this correct?

No. A standard URLSession can work from the background you just have to ensure that the app isn’t suspended while that work is in progress. That may not be possible in the general case but in some cases it’s both possible and useful. For example a BGAppRefreshTaskRequest gives your app some execution time in the background and you can use that to run a network request if you like. Your app will remain running in the background until either you complete the network request (by calling task.setTaskCompleted(success:) on the task) or you run out of background execution time (the task calls your expirationHandler).

For more background (hey hey) on this, see my UIApplication Background Task Notes post. This is cast in terms of the older API but the same basic logic applies.

Having said that, whether this is the right choice depends on a lot of things, the most critical being the size and latency requirements of your transfers.

The main problem with the application is that the user authenticates
via OAuth and the token is only valid for one hour.

This is what urlSession(_:task:willBeginDelayedRequest:completionHandler:) is for.

Again, whether this makes sense in your context depends on the exact details.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

A standard URLSession can work from the background you just have to ensure that the app isn’t suspended while that work is in progress.

Thanks for the clarification regarding the URLSession and the background execution. I've found different information about this.

I think we will use a mixture of both ways. For the initial synchronization we'll use a background session task and for the subsequent synchronization simply a BGAppRefreshTaskRequest. Since these only need to retrieve and process data since the last sync.
Best practice for background synchronization with authorization
 
 
Q