Downloading in background and waking app when finished

假装没事ソ 提交于 2019-12-22 01:13:06

问题


I use URLSession configured as background session to download some files. When download finishes I use:

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)

to move downloaded file. Everything works fine, except that when app is in the background this function is not being called. It's called right after app is restored to foreground, but I would like the system to wake my app after file is downloaded. Is there some way to do this?


回答1:


There is indeed :)

You probably need to change a few things in your setup.

First the URLSessionConfiguration you use should be of type background like so:

URLSessionConfiguration.background(withIdentifier: "your.unique.id.here")

Then, in your AppDelegate you need to implement this method:

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

Where you do something like store the completionHandler so it can be used later on.

And finally, where you normally do your "done downloading" magic... typically here:

 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)

You need to check for the presence of a completionHandler and if present, invoke that.

Example

The last two bits of the above may seem a bit...huh?? so here is an example.

In your AppDelegate you can define an optional for the completionHandler so you can store it for later on:

var backgroundSessionCompletionHandler: (() -> Void)?

and the method then looks like this:

func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
    if identifier == "your.unique.id.here" {
        backgroundSessionCompletionHandler = completionHandler
    }
}

And then you "just" need to call that once you are done processing the downloaded file, which you can do like this:

if  let appDelegate = UIApplication.shared.delegate as? AppDelegate,
    let completionHandler = appDelegate.backgroundSessionCompletionHandler {
        appDelegate.backgroundSessionCompletionHandler = nil
        OperationQueue.main.addOperation {
            completionHandler()
        }
    }

Also, take a look at this tutorial for instance.

Hope that helps you.



来源:https://stackoverflow.com/questions/40395810/downloading-in-background-and-waking-app-when-finished

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!