美文网首页程序员iOS学习开发iOS学习笔记
https网络访问之AFNetworking源码解析

https网络访问之AFNetworking源码解析

作者: 溪石iOS | 来源:发表于2019-01-13 16:35 被阅读8次

    使用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 进行了封装,关键是以下三步:

    1. 根据 challenge.protectionSpace.authenticationMethod 获取服务器认证方法
    2. 创建 NSURLCredential 身份验证证书, credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
    3. 调用 completionHandler,将生成的证书返回。

    自己实现时,在 NSURLSession 的代理对象实现URLSession:task:didReceiveChallenge:completionHandler:方法中完成以上步骤也是可以的。

    相关文章

      网友评论

        本文标题:https网络访问之AFNetworking源码解析

        本文链接:https://www.haomeiwen.com/subject/jiakdqtx.html