Alamofire: [Result]: FAILURE: Error Domain=NSURLErrorDomain Code=-999 “cancelled”

匿名 (未验证) 提交于 2019-12-03 01:33:01

问题:

The service I'm connecting to is using a self signed certificate. For dev purposes I do not want to validate that chain.

Using swift 3 with Alamofire 4. Fixed the ATS accordingly:

<key>NSAppTransportSecurity</key> <dict>     <key>NSExceptionDomains</key>     <dict>         <key>url.com</key>         <dict>             <key>NSExceptionAllowsInsecureHTTPLoads</key>             <true/>             <key>NSExceptionRequiresForwardSecrecy</key>             <false/>             <key>NSIncludesSubdomains</key>             <true/>         </dict>     </dict> </dict> 

Code to connect and disable evaluation.

    let serverTrustPolicies: [String: ServerTrustPolicy] = [         "example.domain.com": .pinCertificates(             certificates: ServerTrustPolicy.certificates(),             validateCertificateChain: false,             validateHost: true         ),         "sub.url.com": .disableEvaluation     ]      let sessionManager = Alamofire.SessionManager(         serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)     )      let headers = ["Authorization": "Basic /*...*/"]      sessionManager.request("https://sub.url.com/path", headers: headers).responseJSON { response in         print(response.request)  // original URL request         print(response.response) // HTTP URL response         print(response.data)     // server data         print(response.result)   // result of response serialization          debugPrint(response)          if let JSON = response.result.value {             print("JSON: \(JSON)")         }     } 

Error log from dumpPrint

[Result]: FAILURE: Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLKey=https://sub.url.com/path, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=https://sub.url.com/path}

URL has been masked.

回答1:

Please add this statement to the end of responseJson block:

manager.session.invalidateAndCancel() 

It happens if the object of the manager is not retained till execution of the block completes, so this would ensure its retention.

Cheers!



回答2:

To retain SessionManager instance you need to capture it in closure passed to responseJSON:

sessionManager.request("https://sub.url.com/path", headers: headers).responseJSON { response in     let _ = sessionManager // retain     // ... } 

Otherwise sessionManager is deallocated shortly it goes out of scope and any executing requests are cancelled.



回答3:

Please check in sessiondidReceiveChallenge: delegate implementation of NSURLSession. Chances are NSURLSessionAuthChallengeCancelAuthenticationChallenge is getting executed somewhere.



回答4:

You need to properly manage the lifetime of your SessionManager instance. Most commonly this is done by making a singleton instance. Otherwise, when your manager goes out of scope and is deinited, all outstanding requests will be cancelled.



回答5:

self.getSessionManager().request(urlstring, method: methods, parameters: parameters, encoding: JSONEncoding.prettyPrinted, headers: Header).responseJSON(queue: nil, options: JSONSerialization.ReadingOptions.allowFragments) { (responseObject) in ... .... }.session.finishTasksAndInvalidate() 

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



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