美文网首页Swift日更
[iOS] NSURLSessionDataTask 取消后,请

[iOS] NSURLSessionDataTask 取消后,请

作者: BudSwift | 来源:发表于2019-05-28 23:03 被阅读0次

    通过手动创建又或者第三方框架(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 取消后,请

        本文链接:https://www.haomeiwen.com/subject/kvxstctx.html