美文网首页
解读AFNetWorking3.x

解读AFNetWorking3.x

作者: 二猪哥 | 来源:发表于2019-02-13 22:33 被阅读0次

    AFNetworking3.x是iOS开发中最常用的第三方开源库之一,它主要用于进行网络请求,其内部实现封装了NSURLSession的网络请求。

    AFNetworking的结构

    AFNetworking主要分为四个模块:

    • 处理请求和回复的序列化模块:Serialization
    • 网络安全模块:Security
    • 网络监测模块:Reachability
    • 处理通讯的会话模块:NSURLSession

    其中NSURLSession是最常使用的模块,也是综合模块,它引用了其他的几个模块,而其他几个模块都是独立的模块,所以对AFNetworking的学习就先从这些单独的模块开始。

    用法

    1.)使用AFNetWorking的时候要对AFHTTPSessionManager进行单例封装(防止内存泄露)

    + (AFHTTPSessionManager *)sharedManager
    {
        static AFHTTPSessionManager *manager = nil;
        static dispatch_once_t predicate;
        dispatch_once(&predicate, ^{
            manager = [AFHTTPSessionManager manager];
            manager.requestSerializer = [AFHTTPRequestSerializer serializer]; // 上传普通格式
            manager.operationQueue.maxConcurrentOperationCount = 5;
            manager.requestSerializer.timeoutInterval=30.f;
            manager.responseSerializer.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml",@"text/html", @"application/json",@"text/plain",nil];
            [manager.requestSerializer setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];
            
        });
        return manager;
    }
    

    2.)处理get请求

    -(void)doGetRequest
    {
        //创建请求地址
        NSString *url=@"http://api.nohttp.net/method";
        //构造参数
        NSDictionary *parameters=@{@"name":@"yanzhenjie",@"pwd":@"123"};
        //AFN管理者调用get请求方法
        [[self shareAFNManager] GET:url parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
            //返回请求返回进度
            NSLog(@"downloadProgress-->%@",downloadProgress);
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            //请求成功返回数据 根据responseSerializer 返回不同的数据格式
            NSLog(@"responseObject-->%@",responseObject);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            //请求失败
            NSLog(@"error-->%@",error);
        }];
    }
    

    3.)处理post请求

    -(void)doPostRequestOfAFN
    {
        //创建请求地址
        NSString *url=@"http://api.nohttp.net/postBody";
        //构造参数
        NSDictionary *parameters=@{@"name":@"yanzhenjie",@"pwd":@"123"};
        //AFN管理者调用get请求方法
        [[self shareAFNManager] POST:url parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
            //返回请求返回进度
            NSLog(@"downloadProgress-->%@",uploadProgress);
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            //请求成功返回数据 根据responseSerializer 返回不同的数据格式
            NSLog(@"responseObject-->%@",responseObject);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            //请求失败
            NSLog(@"error-->%@",error);
        }];
    }
    

    4.)处理文件上传

    -(void)doUploadRequest
    {
        // 创建URL资源地址
        NSString *url = @"http://api.nohttp.net/upload";
        // 参数
        NSDictionary *parameters=@{@"name":@"yanzhenjie",@"pwd":@"123"};
        [[self shareAFNManager] POST:url parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0];
            NSTimeInterval a=[dat timeIntervalSince1970];
            NSString* fileName = [NSString stringWithFormat:@"file_%0.f.txt", a];
            
            [FileUtils writeDataToFile:fileName data:[@"upload_file_to_server" dataUsingEncoding:NSUTF8StringEncoding]];
            // 获取数据转换成data
            NSString *filePath =[FileUtils getFilePath:fileName];
            // 拼接数据到请求题中
            [formData appendPartWithFileURL:[NSURL fileURLWithPath:filePath] name:@"headUrl" fileName:fileName mimeType:@"application/octet-stream" error:nil];
            
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            // 上传进度
            NSLog(@"%lf",1.0 *uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            //请求成功
            NSLog(@"请求成功:%@",responseObject);
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            //请求失败
            NSLog(@"请求失败:%@",error);
        }];
    }
    

    5.)处理文件下载

    -(void)doDownLoadRequest
    {
        NSString *urlStr =@"http://images2015.cnblogs.com/blog/950883/201701/950883-20170105104233581-62069155.png";
        // 设置请求的URL地址
        NSURL *url = [NSURL URLWithString:urlStr];
        // 创建请求对象
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        // 下载任务
        NSURLSessionDownloadTask *task = [[self shareAFNManager] downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
            // 下载进度
            NSLog(@"当前下载进度为:%lf", 1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
        } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
            // 下载地址
            NSLog(@"默认下载地址%@",targetPath);
            //这里模拟一个路径 真实场景可以根据url计算出一个md5值 作为fileKey
            NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0];
            NSTimeInterval a=[dat timeIntervalSince1970];
            NSString* fileKey = [NSString stringWithFormat:@"/file_%0.f.txt", a];
            // 设置下载路径,通过沙盒获取缓存地址,最后返回NSURL对象
            NSString *filePath = [FileUtils getFilePath:fileKey];
            return [NSURL fileURLWithPath:filePath]; // 返回的是文件存放在本地沙盒的地址
        } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
            // 下载完成调用的方法
            NSLog(@"filePath---%@", filePath);
            NSData *data=[NSData dataWithContentsOfURL:filePath];
            UIImage *image=[UIImage imageWithData:data];
            // 刷新界面...
            UIImageView *imageView =[[UIImageView alloc]init];
            imageView.image=image;
            [self.view addSubview:imageView];
            [imageView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.center.equalTo(self.view);
                make.size.mas_equalTo(CGSizeMake(300, 300));
            }];
        }];
        //启动下载任务
        [task resume];
    }
    

    6.)网络状态监听

    - (void)aFNetworkStatus{
        
        //创建网络监测者
        AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
        
        /*枚举里面四个状态  分别对应 未知 无网络 数据 WiFi
         typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
         AFNetworkReachabilityStatusUnknown          = -1,      未知
         AFNetworkReachabilityStatusNotReachable     = 0,       无网络
         AFNetworkReachabilityStatusReachableViaWWAN = 1,       蜂窝数据网络
         AFNetworkReachabilityStatusReachableViaWiFi = 2,       WiFi
         };
         */
        
        [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            //这里是监测到网络改变的block  可以写成switch方便
            //在里面可以随便写事件
            switch (status) {
                case AFNetworkReachabilityStatusUnknown:
                    NSLog(@"未知网络状态");
                    break;
                case AFNetworkReachabilityStatusNotReachable:
                    NSLog(@"无网络");
                    break;
                    
                case AFNetworkReachabilityStatusReachableViaWWAN:
                    NSLog(@"蜂窝数据网");
                    break;
                    
                case AFNetworkReachabilityStatusReachableViaWiFi:
                    NSLog(@"WiFi网络");
                    break;
                    
                default:
                    break;
            }
            
        }] ;
        
        [manager startMonitoring];
    }
    

    7.) 在2017年1月1日起Apple 要求开发者于年底之前为提交至 App Store 中的应用启用 HTTPS ,以支持 iOS 9 引入的 ATS(App Transport Security)技术。但后来,apple 发布声明宣布延长这个时限,提供给开发者更多的时间进行相关准备。目前 Apple 尚未公布新的截止日期。

    首先找后台要一个证书(SSL证书,一般你跟后台说要弄https,然后让他给你个证书,他就知道了),我们需要的是.cer的证书。但是后台可能给我们的是.crt的证书。我们需要转换一下:打开终端 -> cd到.crt证书路径 -> 输入openssl x509 -in 你的证书.crt -out 你的证书.cer -outform der,证书就准备好了,拖入工程,记得选copy。

    //支持https
    + (AFSecurityPolicy *)customSecurityPolicy
    {
        //先导入证书,找到证书的路径
        NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"你的证书名字" ofType:@"cer"];
        NSData *certData = [NSData dataWithContentsOfFile:cerPath];
    
        //AFSSLPinningModeCertificate 使用证书验证模式
        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    
        //allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
        //如果是需要验证自建证书,需要设置为YES
        securityPolicy.allowInvalidCertificates = YES;
    
        //validatesDomainName 是否需要验证域名,默认为YES;
        //假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
        //置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
        //如置为NO,建议自己添加对应域名的校验逻辑。
        securityPolicy.validatesDomainName = NO;
        NSSet *set = [[NSSet alloc] initWithObjects:certData, nil];
        securityPolicy.pinnedCertificates = set;
    
        return securityPolicy;
    }
    
    + (AFHTTPSessionManager *)sharedManager
    {
        static AFHTTPSessionManager *manager = nil;
        static dispatch_once_t predicate;
        dispatch_once(&predicate, ^{
            manager = [AFHTTPSessionManager manager];
            manager.requestSerializer = [AFHTTPRequestSerializer serializer]; // 上传普通格式
            [manager setSecurityPolicy:[FactoryUI customSecurityPolicy]];
            manager.operationQueue.maxConcurrentOperationCount = 5;
            manager.requestSerializer.timeoutInterval=30.f;
            manager.responseSerializer.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml",@"text/html", @"application/json",@"text/plain",nil];
            [manager.requestSerializer setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];
            
        });
        return manager;
    }
    

    相关文章

      网友评论

          本文标题:解读AFNetWorking3.x

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