【问题标题】:Alamofire Error Domain=NSURLErrorDomain Code=-999 "cancelled"Alamofire 错误域=NSURLErrorDomain 代码=-999 “已取消”
【发布时间】:2017-03-19 17:58:51
【问题描述】:

我已经成功获得了我的令牌的钥匙串并将其传递给如下所示的 AccessTokenAdapter 类。 http127.0.0.1:8000/api2/projects/?format=json 作为 projectsURL 传递。

    class AccessTokenAdapter: RequestAdapter {
        private let accessToken: String

        init(accessToken: String) {
            self.accessToken = accessToken
        }

        func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
            var urlRequest = urlRequest
         //   print("JWT \(accessToken)")
            urlRequest.setValue("JWT \(accessToken)", forHTTPHeaderField: "Authorization")

            return urlRequest
        }
    }


    let sessionManager = SessionManager()
    sessionManager.adapter = AccessTokenAdapter(accessToken: self.keychain["token"]!)

    sessionManager.request(self.projectsURL, method: .get, encoding: JSONEncoding.default).responseJSON{ response in
        switch response.result {
        case .success:
            print("yey I made it")
        case .failure(let error):
            print(error)
        }
    }

然而,从打印(错误),我的 Xcode 显示错误,如 错误域=NSURLErrorDomain 代码=-999 "取消" UserInfo={NSErrorFailingURLKey=http://127.0.0.1:8000/api2/projects/?format=json, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=http127.0.0.1:8000/api2/projects/?format=json}

有什么想法吗?
Alamofire 4.0
钥匙扣
Xcode 8.1
斯威夫特3
使用 JWT 进行身份验证
使用带有 header、key = "Authentication"、value = "JWT (token generated here)" 的 Postman 工作正常

【问题讨论】:

    标签: json swift xcode alamofire keychain


    【解决方案1】:

    当你将 sessionManager 设置为 let 常量时,它不会比包含它的函数活得更久,因此一旦管理器被释放,会话就会结束。

    要解决此问题,请延长 sessionManager 的寿命。例如,在我的情况下,我将其设为类属性:

    class NetworkRequest: {
    
       var sessionManager = Alamofire.SessionManager()
    
       ...
    
       func performRequest(_ call: APICall, customLink: String = "", parameters: Dictionary<String, Any> = ["":"" as Any]) {
    
            let sessionConfig = URLSessionConfiguration.default
            sessionConfig.timeoutIntervalForRequest = call.suggestedTimeout()
            sessionConfig.timeoutIntervalForResource = call.suggestedTimeout()
            sessionManager = Alamofire.SessionManager(configuration: sessionConfig)
            sessionManager.adapter = AccessTokenAdapter()
    
            sessionManager.request(urlString,
                          method: call.method(),
                          parameters: parameters,
                          encoding: call.chooseEncoding(),
                          headers: [:])
            .responseJSON
            { response in
              ...
            }
    

    }

    根据您的情况,解决方案可能会有所不同,但想法是让 sessionManager 保持活动状态,直到网络请求结束。

    【讨论】:

      【解决方案2】:
      self.getSessionManager()
                       .request(urlstring, 
                                method: methods, 
                                parameters: parameters, 
                                encoding: JSONEncoding.prettyPrinted, 
                                headers: Header
                        ).responseJSON(
                               queue: nil, 
                               options: JSONSerialization.ReadingOptions.allowFragments
      ) { (responseObject) in
       // response parsing code is here
      }.session.finishTasksAndInvalidate() 
      

      只要把任务完成后失效的方法,就是session.finishTasksAndInvalidate()

      一切都很好。

      【讨论】:

        【解决方案3】:

        这个错误通常是由于你创建的 SessionManager 超出范围而被取消初始化,你的请求将被取消。保留对它的引用,我的解决方案是使用变量将 SessionManager 存储在您的 APIService 类中

          public lazy var sharedManager: SessionManager = {
            let configuration = URLSessionConfiguration.default
        
            configuration.timeoutIntervalForRequest = 60
            configuration.timeoutIntervalForResource = 60
        
            let manager = Alamofire.SessionManager(configuration: configuration)
            return manager
        }()
        

        【讨论】:

        • 我同意这一点。当保持对它的引用时。效果很好
        【解决方案4】:

        刚刚解决。貌似需要提前设置httpmethod。

            let url = URL(string: "http://127.0.0.1:8000/api2/projects/?format=json")
            var urlRequest = URLRequest(url:url!)
            urlRequest.httpMethod = HTTPMethod.get.rawValue
            urlRequest.addValue("JWT \(self.keychain["token"]!)", forHTTPHeaderField: "Authorization")
            urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
            Alamofire.request(urlRequest)
                .responseJSON { response in
                    debugPrint(response)
            }
        

        【讨论】:

          【解决方案5】:

          如果其他人和我一样遇到这个问题,而且这不是 https 问题或我发现的许多其他 SO 帖子中给出的其他答案,我得到这个并发现原因是控制器提出请求,但不显示控制器。有点像如果您有一些仅出现在特定条件下的控制器,并且它本身会发出在 viewWillAppear 或其他中完成的请求。我使用了一个基类来确定条件控制器中的调用是否应该尝试请求。这解决了我的问题。

          【讨论】:

            猜你喜欢
            • 2017-03-14
            • 1970-01-01
            • 1970-01-01
            • 2021-10-24
            • 1970-01-01
            • 2020-02-22
            • 2015-11-18
            • 2019-04-22
            • 2016-01-18
            相关资源
            最近更新 更多