Reputation: 525
I have a syncing functionality, where a series of downloads happens in the background.
For that, I create a URLSession instance with background configuration as below:
let config = URLSessionConfiguration.background(withIdentifier: "BackgroundSessionDL")
config.httpMaximumConnectionsPerHost = 20
self.session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
Each of the download tasks (which may be in a number of few hundreds) is added as follows:
var request = URLRequest(url: url)
request.addValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let downloadTask = self.session.downloadTask(with: request)
downloadTask.resume()
This code works perfectly on iOS 12 or earlier - the download continues even in the background for the tasks already added. But, for iOS 13, causes issue as follows:
I tried to search whether any new classes/framework introduced by Apple for background task download on iOS 13, but did not find anything on this. Also, class used in earlier versions, for representation of a background download task, is still NOT deprecated in iOS 13 and is the only result when searched for background download on iOS 13. Similarly, background configuration used for the HTTP session, is still NOT deprecated. So, I believe the current background download implementation is the one recommended by Apple. (As per my understanding, "BGTaskScheduler" is not intended for this, please correct me if wrong).
So, is this due to any newly introduced bug in iOS 13? OR any change in this implementation, specific to iOS 13, is expected by Apple?
Edit:
I have already added the handleEventsForBackgroundURLSession
callback. Found that the respective logs are not printed and app size does not increase in Settings on iOS 13. So, it appears that download does not continue in the background and it is not related to download related callbacks not getting invoked.
Upvotes: 6
Views: 2648
Reputation: 2099
I guess that if you run the app in the foreground then everything works as expected however as soon as the app is put into the background no callback are received anymore
BackgroundDownloader only works when the app is in the foreground but there is a specific support when the app enters a suspended/backgrounded state.
When an app is in a suspended/terminated state and a download is completed, iOS will wake the app up (in the background) by calling:
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
//TODO: Handle processing downloads
}
}
The behavior change between ios12 and ios13 is probably not related to some API changes but just with a more aggressive power saving policy for app while they are not in foreground
Modify the URLSession background configuration identifier Making the isDiscretionary as false in order to avoid OS scheduling the background request transfers due to battery or performance The most important one shouldUseExtendedBackgroundIdleMode as true. This is the ultimate line that makes the TCP sockets open even when the app is locked or suspended.
Upvotes: 3