Alamofire Error Domain=NSURLErrorDomain Code=-999 “cancelled”

醉酒当歌 提交于 2019-11-30 17:08:17

问题


I already have successfully got keychain for my token and passing it to AccessTokenAdapter class shown below. http127.0.0.1:8000/api2/projects/?format=json is passed as 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)
        }
    }

however, from print(error), my Xcode shows error like Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLKey=http://127.0.0.1:8000/api2/projects/?format=json, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=http127.0.0.1:8000/api2/projects/?format=json}

Any ideas?
Alamofire 4.0
Keychain
Xcode 8.1
Swift3
Using JWT for authentication
Using Postman with header, key = "Authentication", value = "JWT (token generated here)" works fine


回答1:


When you make sessionManager a let constant it won't live longer than the embracing it function, thus the session ends as soon as the manager is deallocated.

To fix this, make sessionManager live longer. For example in my case I made it a class property:

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
          ...
        }

}

The solution might be different according to your situation, but the idea is to keep sessionManager alive until the network request ends.




回答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() 

Just put the method of invalidate after task finish, means session.finishTasksAndInvalidate()

All works great.




回答3:


Just solved. Looks like it's required to set httpmethod beforehand.

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



回答4:


In case other run into this as well as I did and it wasn't a https issue or other answer given in the many other SO posts that I found, I was getting this and found the cause to be a controller that was making a request but the controller was not to be shown. Kind of like if you have some controller that appears only on specific conditional and it, itself makes a request which is done in the viewWillAppear or other. I used a base class that determines if the call in the conditional controller should attempt the request or not. This fixed the problem for me.




回答5:


This error usually caused by the SessionManager you created falling out of scope and being deinited, and your requests will be cancelled. Keep a reference to it, my solution is using a variable to store SessionManager in your APIService class

  public lazy var sharedManager: SessionManager = {
    let configuration = URLSessionConfiguration.default

    configuration.timeoutIntervalForRequest = 60
    configuration.timeoutIntervalForResource = 60

    let manager = Alamofire.SessionManager(configuration: configuration)
    return manager
}()


来源:https://stackoverflow.com/questions/40447436/alamofire-error-domain-nsurlerrordomain-code-999-cancelled

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