[iOS] NSURLSessionDataTask 取消后,请求会回调吗?如何判断控制器是 push / pop(2/365)

通过手动创建又或者第三方框架(AFNetworking、Alamofire)发起一个请求后,一般都会返回一个请求任务,也就是 NSURLSessionDataTask 类型的对象,比如:

let url1 = URL(string: "https://www.qq.com")!
        let urlTask = URLSession.shared.dataTask(with: url1) { (data: Data?, resp: URLResponse?, error: Error?) in
            print(data as Any, resp as Any, error as Any)
        }
        urlTask.resume()

如果这个请求由一个控制器发起,比如说查看某个订单的详情,有一个良好的实践时,在页面 pop 出栈 viewWillDisappear: 时取消该请求,比如这样:

override viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    if (isLeaving) {  // 见下文分析
        urlTask.cancel()
    }
}

通过日志可以可以看到结论:
在成功或者失败回调进行手动取消的请求,最后会以失败的方式回调

Task <8AC12E49-CC35-4E32-87DC-69457E9210BA>.<1> finished with error - code: -999

(Data) nil
(URLResponse) nil 
(Error) Optional(Error Domain=NSURLErrorDomain 
Code=-999 "cancelled" 
UserInfo={
    NSErrorFailingURLStringKey=https://www.qq.com/, 
    NSLocalizedDescription=cancelled, 
    NSErrorFailingURLKey=https://www.qq.com/
})

由此可以判断出 Domain 为 NSURLErrorDomain,code = -999 的是手动取消的请求,可以判断做特别的处理。

如何判断控制器是被 pop 出栈呢?

在参考文献《iOS判断UIViewController是被Push还是被Pop或者被Present或Dismiss》中可以从 UIViewController 类中看到如下属性:

 @available(iOS 5.0, *)
    open var isBeingPresented: Bool { get }

    @available(iOS 5.0, *)
    open var isBeingDismissed: Bool { get }

    @available(iOS 5.0, *)
    open var isMovingToParent: Bool { get }

    @available(iOS 5.0, *)
    open var isMovingFromParent: Bool { get }

其中的注释如下:

These four methods can be used in a view controller's appearance callbacks to determine if it is being
presented, dismissed, or added or removed as a child view controller. For example, a view controller can
check if it is disappearing because it was dismissed or popped by asking itself in its viewWillDisappear:
method by checking the expression ([self isBeingDismissed] || [self isMovingFromParentViewController]).

结合注释可以很轻松地得出结论:

extension UIViewController {
    var isLeaving: Bool { 
          return isBeingDismissed || isMovingFromParentViewController
    }
}

加个微信,随时联系

你可能感兴趣的:([iOS] NSURLSessionDataTask 取消后,请求会回调吗?如何判断控制器是 push / pop(2/365))