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

Sam*_*rek 9 xcode ios swift alamofire

我要连接的服务是使用自签名证书.出于开发目的,我不想验证该链.

使用swift 3和Alamofire 4.相应地修正了ATS:

<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>
Run Code Online (Sandbox Code Playgroud)

用于连接和禁用评估的代码.

    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)")
        }
    }
Run Code Online (Sandbox Code Playgroud)

来自dumpPrint的错误日志

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

网址已被屏蔽.

mix*_*xel 12

要保留SessionManager实例,您需要在传递给它的闭包中捕获它responseJSON:

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

否则sessionManager将很快释放它超出范围并且任何正在执行的请求都将被取消.

  • 然后应该适当延长生命周期,可能是将管理器存储在某个地方并在时机到来时正确地取消它.强制本地引用只是为了保持一些活着的东西总是反模式的,因为这意味着你没有正确处理变量的生命周期. (2认同)

小智 8

请将此语句添加到responseJson块的末尾:

manager.session.invalidateAndCancel()
Run Code Online (Sandbox Code Playgroud)

如果在块的执行完成之前不保留管理器的对象,则会发生这种情况,因此这将确保其保留.

干杯!