简体   繁体   中英

When to call completionHander after background push received? Background download after push not working consistently in iOS9

Without exception, every code example I've seen of using didReceiveRemoteNotification:fetchCompletionHander: is like this:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)
{
    do something
    completionHandler(UIBackgroundFetchResult.NewData)
}

Now the main point of background push is for the app to fetch data in the background, therefore do something will be asynchronous.

The documentation for this method states: "[refering to the completion handler] The block to execute when the download operation is complete ."

But if do something is asynchronous then completionHandler is being called immediately and not when the operation is complete. Therefore all the code examples are inconsistent with the documentation.

I've been using background push/download like this in a few projects since it was introduced without a problem. However with iOS9 I am finding any calls make to NSURLConnection from do Something are not executing (they will if the push is sent soon after the app moves to the background, but not if its been in the background for several minutes)

I'm wondering if this is related to when completionHander is called or something else. I'm going to do some experiments to test that out but in the meanwhile wondering if anybody else has seen this change in behavior with iOS9?

[Please no flippant unhelpful comments about NSURLConnection being deprecated in iOS 9, deprecated does not mean unavailable, and it should not mean no longer working]

Typically if you need to kick off network calls in the "do something" portion of your example then you would implement a background session via NSURLSession. You create and "resume" a download task and then the iOS will wake your app up again when it is finished (via didFinishDownloading of the delegate). At that point you have some more time to process the response or store it somewhere on disk to process later when the app is active.

You only have about 30 seconds to call the completion handler. If you don't want to use NSURLSession and want to use NSURLConnection then you can try not calling the completion handler until after the asynchronous call via NSURLConnection returns. But again, if it takes too long then the iOS will kill your process anyway.

I hope that wasn't unhelpful.

I am having a different issue where I'm using NSURLSession and it works fine in iOS8 but in iOS9 it almost immediately calls applicationWillTerminate after starting a download request. Once that happens the app is DOA until it is manually launched again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM