使用AFNetworking 访问https
我们尝试访问https://www.apple.com/
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
[manager GET:@"https://www.apple.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSString *str =[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(@"~~~success:%@", str);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
获得的数据是NSData格式的html数据,转换为NSString 打印后可看到是正常网页的内容:
获得的https数据
AFNetworking 源码解析:
对比普通http 代码,似乎只是把url中 http 换成https,实际上当然没这么简单,AFNetworking 帮我们做了一些必要的工作,我们到AFNetworkig 的源码去看看:
- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
__block NSURLCredential *credential = nil;
if (self.sessionDidReceiveAuthenticationChallenge) {
disposition = self.sessionDidReceiveAuthenticationChallenge(session, challenge, &credential);
} else {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
if (credential) {
disposition = NSURLSessionAuthChallengeUseCredential;
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
} else {
disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
}
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
}
if (completionHandler) {
completionHandler(disposition, credential);
}
}
URLSession 代理中的关键步骤
可见,AFNetworking 是对系统库 NSURLSession 进行了封装,关键是以下三步:
- 根据
challenge.protectionSpace.authenticationMethod
获取服务器认证方法 - 创建 NSURLCredential 身份验证证书,
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
- 调用 completionHandler,将生成的证书返回。
自己实现时,在 NSURLSession 的代理对象实现URLSession:task:didReceiveChallenge:completionHandler:方法中完成以上步骤也是可以的。
网友评论