美文网首页
iOS AFNetworking 3.0 适配HTTPS (HT

iOS AFNetworking 3.0 适配HTTPS (HT

作者: OnlyFunny | 来源:发表于2017-02-14 18:02 被阅读0次

    这是我在简书发的第一篇技术文章, 在工作间隙我觉得还是有必要把工作中遇到的问题, 包括调研的一些知识点做一个记录, 希望可以对大家有所帮助.


    长话短说, 直接上干货!


    ATS是在2015年由苹果引入的强化网络传输安全的标准,要求所有的App在从Web端获取数据的时候都要使用安全的HTTPS链接,并进一步强调要使用最新的TLS1.2版本的HTTPS。
    首先需要服务器端升级到https,拿到服务器哥们提供的server.pem证书文件,并导入到项目中

    项目地址

    - (AFSecurityPolicy *)customSecurityPolicy
    {
        /* 导入证书 (证书在这里暂时不能公开, 防止盗用, 主要看实现代码吧)**/
        NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"duoyundong.yoger.cn" ofType:@"cer"];//证书的路径
        NSData *certData = [NSData dataWithContentsOfFile:cerPath];
        
        // AFSSLPinningModeCertificate 使用证书验证模式
        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
        
        /* 如果是需要验证自建证书,需要设置为YES**/
        securityPolicy.allowInvalidCertificates  = YES;
        securityPolicy.validatesDomainName  = NO;
        
        /** 如果certData为空会导致崩溃问题, 这里需要加一个判断*/
        if (certData) {
            securityPolicy.pinnedCertificates = [NSSet setWithArray:@[certData]];
        }
        return securityPolicy;
    }
    

    /*** 具体还是下载测试项目, 代码以项目为准 ***/

    /**
     *  网络请求 (POST / GET)
     *
     *  @param path         接口拼接路径
     *  @param params       请求体
     *  @param method       get / post
     *  @param successBlock 成功
     *  @param failureBlock 失败
     *  @param refreshBlock 刷新
     */
    - (void)sendRequestPath:(NSString *)path
                     params:(NSDictionary *)params
                     method:(NSString *)method
                    success:(APISuccessBlock)successBlock
                    failure:(APIFailureBlock)failureBlock
                      error:(APIRefreshBlock)refreshBlock
    {
        /** 实时监测网络状态*/
        [[NetworkJudgement defaultInstance] judgeNetWorkIsAvailable];
        /** 初始化通知(断网时接收)*/
        [self receiveNotification];
        
        
        NSString *fullPath = [NSString stringWithFormat:kMainUrl_HTTPS, path];
        
        _sessionManager = [AFHTTPSessionManager manager];
        _sessionManager.securityPolicy.allowInvalidCertificates = YES;
        _sessionManager.requestSerializer.timeoutInterval = kRequestTimeOutInterval;
        
        _sessionManager.responseSerializer = [AFJSONResponseSerializer serializer];
        [_sessionManager.responseSerializer setAcceptableContentTypes: [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"text/css", nil]];
        
        // 验证HTTP+SSL证书
        [_sessionManager setSecurityPolicy:[self customSecurityPolicy]];
        
        if ([[method lowercaseString] isEqualToString:@"get"]) {
            
            if(IOS_VERSION <= 7.0f) {
                
                fullPath = [fullPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
                
            } else {
                
                fullPath = [fullPath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"`#%^{}\"[]|\\<> "].invertedSet];
            }
            
            
            [_sessionManager GET:fullPath parameters:params progress:^(NSProgress * _Nonnull downloadProgress) {
                
            } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                
                [self successDataTask:task ResponseObject:responseObject success:successBlock failure:failureBlock refresh:refreshBlock];
                
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                
                [self errorOperation:failureBlock refresh:refreshBlock];
            }];
            
        } else if ([[method lowercaseString] isEqualToString:@"post"]) {
            
            if(IOS_VERSION <= 7.0f) {
                
                fullPath = [fullPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
                
            } else {
                
                fullPath = [fullPath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"`#%^{}\"[]|\\<> "].invertedSet];
            }
            
            
            [_sessionManager POST:fullPath parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
                
            } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                
                [self successDataTask:task ResponseObject:responseObject success:successBlock failure:failureBlock refresh:responseObject];
                
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                
                failureBlock(error);
                
    //            [self errorOperation:failureBlock refresh:refreshBlock];
            }];
        }
    }
    

    AFN常见错误

    //1.创建一个管理者
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
        //1.0 改请求的默认的序列化方式 改成JSON格式的请求(请求为json格式的二进制)
    //会把字典,数组转化成json格式的二进制传给服务器。
    //默认情况下是普通的二进制,实现此方法改为JSON格式的二进制
        manager.requestSerializer = [AFJSONRequestSerializer serializer];
    
        //1.1 改默认的响应反序列化方式 改为普通二进制(服务器返回的是二进制,afn不做处理)。
    //默认情况下 afn会做二进制转为json的格式的处理。然后我们自己把json转成数组,或字典。
    //实现此方法后不做处理,直接将二进制说句给你。也不再需要1.2 增加默认的返回方式(JSON)的可接收的类型。
        manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
        //1.2 增加默认的返回方式(JSON)的可接收的类型
        //manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/plain"];
    

    常见问题
    注意:如果服务器升级到TLS1.1还是不行的,因为苹果要求使用TLS1.2 SSL加密请求数据。会造成无法接受数据

    其他相关文章推荐
    浅谈iOS语音识别+语音播报
    iOS开发中 weak和assign的区别
    Objective-C沙盒结构
    浅谈AutoreleasePool底层是如何实现的?
    iOS开发中内联函数(UIKIT_STATIC_INLINE)的使用
    邓白氏编码(DUNS)申请流程 (史上最全)
    AppStore个人开发者账号升级为公司账号(邓白氏码DUNS申请等)

    相关文章

      网友评论

          本文标题:iOS AFNetworking 3.0 适配HTTPS (HT

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