最近不知道使用 HTTPS 的猴子们有没有遇到这种错误呢?
CFNetwork SSLHandshake failed (-9801)
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
后面的数字可以忽略掉,他们可以算作是同一种错误.不说没用的,现在就说解决办法,先来看看苹果的官方文档是怎么说的.
NSURLSession allows you to customize HTTPS server trust evaluation by implementing the -URLSession:didReceiveChallenge:completionHandler: delegate method. To customize HTTPS server trust evaluation, look for a challenge whose protection space has an authentication method of NSURLAuthenticationMethodServerTrust. For those challenges, resolve them as described below. For other challenges, the ones that you don't care about, call the completion handler block with the NSURLSessionAuthChallengePerformDefaultHandling disposition and a NULL credential.
When dealing with the NSURLAuthenticationMethodServerTrust authentication challenge, you can get the trust object from the challenge's protection space by calling the -serverTrust method. After using the trust object to do your own custom HTTPS server trust evaluation, you must resolve the challenge in one of two ways:
If you want to deny the connection, call the completion handler block with the NSURLSessionAuthChallengeCancelAuthenticationChallenge disposition and a NULL credential.
If you want to allow the connection, create a credential from your trust object (using +[NSURLCredential credentialForTrust:]) and call the completion handler block with that credential and the NSURLSessionAuthChallengeUseCredential disposition.
Important: The system ignores the trust result of the trust object you use to create the credential; any valid trust object will allow the connection to succeed.
上面的意思就是说,NSURLSession 运行自定义服务器信任评价,通过实施 URLSessionDelegate 的代理方法
-URLSession:didReceiveChallenge:completionHandler:可以自定义服务器信任评价,中间还说了什么自己翻译吧.
关于实现自定义服务器信任评价有两中选择,一是不允许链接,我自己的理解,另一种就是NSURLCredential的对象,然后在上述的代理方法中回调代理方法中的 block 函数,然后就完事了,代码实现如下:
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
{
SecTrustRef tmpSecTrustRef = challenge.protectionSpace.serverTrust;
NSURLCredential *credential = [NSURLCredential credentialForTrust:tmpSecTrustRef];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
}
最后,还有一点需要做的是别忘记配置你的info.plist 文件,没有配置,只实现代码是没有用的,经过验证得到的结果.关于配置的部分如下截图:
现在,可以很随意的访问了.