diff --git a/ios/App/App/AppDelegate.swift b/ios/App/App/AppDelegate.swift index b37c9931..01115c80 100644 --- a/ios/App/App/AppDelegate.swift +++ b/ios/App/App/AppDelegate.swift @@ -6,6 +6,7 @@ import RealmSwift class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? + var backgroundCompletionHandler: (() -> Void)? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. @@ -72,6 +73,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // tracking app url opens, make sure to keep this call return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler) } + + func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) { + // Stores the completion handler for background downloads + // The identifier of this method can be ignored at this time as we only have one background url session + backgroundCompletionHandler = completionHandler + } override func touchesBegan(_ touches: Set, with event: UIEvent?) { super.touchesBegan(touches, with: event) diff --git a/ios/App/App/plugins/AbsDownloader.swift b/ios/App/App/plugins/AbsDownloader.swift index d430fd5e..22c42730 100644 --- a/ios/App/App/plugins/AbsDownloader.swift +++ b/ios/App/App/plugins/AbsDownloader.swift @@ -15,9 +15,10 @@ public class AbsDownloader: CAPPlugin, URLSessionDownloadDelegate { static private let downloadsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] private lazy var session: URLSession = { + let config = URLSessionConfiguration.background(withIdentifier: "AbsDownloader") let queue = OperationQueue() queue.maxConcurrentOperationCount = 5 - return URLSession(configuration: .default, delegate: self, delegateQueue: queue) + return URLSession(configuration: config, delegate: self, delegateQueue: queue) }() private let progressStatusQueue = DispatchQueue(label: "progress-status-queue", attributes: .concurrent) private var downloadItemProgress = [String: DownloadItem]() @@ -78,6 +79,18 @@ public class AbsDownloader: CAPPlugin, URLSessionDownloadDelegate { } } + // Called when downloads are complete on the background thread + public func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) { + DispatchQueue.main.async { + guard let appDelegate = UIApplication.shared.delegate as? AppDelegate, + let backgroundCompletionHandler = + appDelegate.backgroundCompletionHandler else { + return + } + backgroundCompletionHandler() + } + } + private func handleDownloadTaskUpdate(downloadTask: URLSessionTask, progressHandler: DownloadProgressHandler) { do { guard let downloadItemPartId = downloadTask.taskDescription else { throw LibraryItemDownloadError.noTaskDescription }