NSURLSession with background configuration and app killed by user

时间秒杀一切 提交于 2021-01-29 02:35:57

问题


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
}()

回答1:


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.



来源:https://stackoverflow.com/questions/40613525/nsurlsession-with-background-configuration-and-app-killed-by-user

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