当前位置: 动力学知识库 > 问答 > 编程问答 >

ios - NSURLSession with background configuration and app killed by user

问题描述:

This is the scenario:

  • NSURLSession with background Configuration
  • Download or upload task start with Bad or No Internet Connection.
  • User close the App.
  • If iOS get Internet Connection will star session task. However,
  • With task still waiting for Internet.
  • User kills the App
  • System cancel all pending tasks

The Question

It is possible to know when the user opens the app again that the tasks were cancelled?

If yes, where?


This Answer says yes, it is possible, but I can not get any callback returning me an error.

I'm using Alamofire to handle all my Networking calls. However, I doubt that Alamofire will change the behavior.


Edit 1

/// Networking manager with Background Session Configuration

static var backgroundManager: Alamofire.Manager = {

let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("com.xxx.NetworkingManager.Identifier")

configuration.HTTPAdditionalHeaders = Manager.defaultHTTPHeaders

let backgroundManager = Alamofire.Manager(configuration: configuration)

return backgroundManager

}()

网友答案:

Kudos to Rob because he showed me the right path.

So after the user kills the app, the system cancels all the pending tasks.


You can see that with the system.log:

Simulator/Debug/Open System Log...

How to catch what was already ongoing?

Instantiate again your Background NSURLSession. Do it elsewhere, but I'll do it in AppDelegate for this example.

The system knows (thanks to the identifier) that it is the same Background Session that before so it maps the pending tasks.

Then retrieve all the tasks. The canceled tasks are still there

The tasks will have a error that you can check.

Error Domain=NSURLErrorDomain Code=-999 "(null)" 
UserInfo={NSErrorFailingURLStringKey=http://your.api.com/url,     
NSURLErrorBackgroundTaskCancelledReasonKey=0,        
NSErrorFailingURLKey=http://your.api.com/url}

Also, with the tasks, you will get the Request URL, so you can map your app requests and do something.

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {


    // This is the code for Swift 2.x. In Swift 3.x this call is a bit different.
    NetworkingManager.backgroundManager.session.getTasksWithCompletionHandler { (data, upload, download) in

        for task in data {

            NSLog("\(task.error)")
        }

        for task in upload {

            NSLog("\(task.error)")
        }

        for task in download {

            NSLog("\(task.error)")

            let reason = task.error?.userInfo[NSURLErrorBackgroundTaskCancelledReasonKey] as? Int
            let code = task.error?.code

            if reason == NSURLErrorCancelledReasonUserForceQuitApplication &&
                code == NSURLErrorCancelled {

                NSLog("\(task.originalRequest)")
                NSLog("\(task.currentRequest?.URL)")
            }
        }
    }
}

NSURLErrorCancelledReasonUserForceQuitApplication -> The operation was canceled because the user forced the app to quit.

So we are on the right track. If someone has a better solution, please share! I do not really like the mapping solution of my requests urls.

分享给朋友:
您可能感兴趣的文章:
随机阅读: