美文网首页A知识点2iOS精華网络相关
iOS9之后AFNetWorking的使用(详细)

iOS9之后AFNetWorking的使用(详细)

作者: 会跳舞的狮子 | 来源:发表于2016-05-13 21:27 被阅读14471次

    AFNetWorking的介绍(给没使用过的读者看的)

    • AFNetWorking是目前iOS开发者网络库中最多的选择
    • AFNetWorking是对NSURLConnection和NSURLSession的封装,iOS 9(AFN3.0版本)之后删除了NSURLConnection的API的所有支持,完全基于NSURLSession 的API.

    介绍下2.0版本跟3.0版本使用的区别

    2.0版本:

    使用 AFHTTPRequestOperationManager这个网络管理者

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    [manager GET:@"需要请求的url" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
            NSLog(@"请求成功");
    } failure:^(AFHTTPRequestOperation *operation, NSError*error) {
            NSLog(@"请求失败");
    }];
    
    3.0版本:

    使用 AFHTTPSessionManager 这个网络管理者

    AFHTTPSessionManager *session = [AFHTTPSessionManager manager];
    [session GET:@"需要请求的url" parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
            NSLog(@"请求成功");
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
            NSLog(@"请求失败");        
    }];
    

    为什么会废弃NSURLConnection而使用NSURLSession这个网络类呢?

    • 从iOS7之后,苹果就推出了NSURLSession , AFN跟随着苹果的脚步,加入了对其的支持
    • NSURLSession推出后苹果大力推广,但是其效果和NSURLConnection效果差不多,为什么NSURLConnection还会被废弃呢?
    • 因为:2015年的WWDC大会,HTTP2.0时代的到来,(1.1版本是99年),HTTP2.0比之前的版本速度更快
    • iOS9(Xcode7)之后, NSURLSession开始正式支持HTTP2.0,所以相比速度快差不多4倍, NSURLSession将NSURLConnection甩开了距离
    • 纯属个人理解

    AFNetWorking的使用(直接上代码)

    • GET请求
    -(void)get
    {
        //1.创建会话管理者
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        
        //2.封装参数
        NSDictionary *dict = @{
                               @"username":@"Lion",
                               @"pwd":@"1314",
                               @"type":@"JSON"
                               };
        //3.发送GET请求
        /*
         第一个参数:请求路径(NSString)+ 不需要加参数
         第二个参数:发送给服务器的参数数据
         第三个参数:progress 进度回调
         第四个参数:success  成功之后的回调(此处的成功或者是失败指的是整个请求)
            task:请求任务
            responseObject:注意!!!响应体信息--->(json--->oc))
            task.response: 响应头信息
         第五个参数:failure 失败之后的回调
         */
        [manager GET:@"需要请求的URL" parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSLog(@"success--%@--%@",[responseObject class],responseObject);
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            NSLog(@"failure--%@",error);
        }];
    }
    
    
    • POST请求和GET请求一样,只需要换成POST请求方法
      [manager POST:@"需要请求的URL" parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSLog(@"success--%@--%@",[responseObject class],responseObject);
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            NSLog(@"failure--%@",error);
        }];
    
    • 下载操作(不是离线下载,离线下载需要自己手动处理)
    -(void)download
    {
        //1.创建会话管理者
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        
        //2.确定请求路径
        NSURL *url = [NSURL URLWithString:@"需要请求的URL"];
        
        //3.创建请求对象
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        
        //4.发送网络请求下载文件
        /*
         第一个参数:请求对象
         第二个参数:progress 进度回调
                    downloadProgress
                    @property int64_t totalUnitCount;
                    @property int64_t completedUnitCount;
         第三个参数:destination 让我们告诉系统应该把文件存放到什么地方
                    内部自动的完成剪切处理
         第四个参数: completionHandler 完成之后的回调
                    response 响应头信息
                    filePath  文件最终的存储路径
                    error 错误信息
         */
        [[manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
            
            NSLog(@"%f",1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
            
        } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
            
            //拼接文件的全路径
            NSString *fullpath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
            
            NSLog(@"fullpath == %@",fullpath);
            return [NSURL fileURLWithPath:fullpath];
            
        } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
    
            NSLog(@"%@",filePath);
        }] resume];
        
    }
    
    • 上传操作
    -(void)upload
    {
        //1.创建会话管理者
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        
        //2.发送请求上传文件
        /*
         第一个参数:请求路径(NSString)
         第二个参数:非文件参数
         第三个参数:constructingBodyWithBlock 拼接数据(告诉AFN要上传的数据是哪些)
         第四个参数:progress 进度回调
         第五个参数:success 成功回调 
            responseObject:响应体
         第六个参数:failure 失败的回调
         */
        [manager POST:@"需要请求的URL" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            
            NSData *data = [NSData dataWithContentsOfFile:@"/Users/apple/Desktop/Snip20160409_148.png"];
            //拼接数据
            /*
             第一个参数:文件参数 (二进制数据)
             第二个参数:参数名~file
             第三个参数:该文件上传到服务器以什么名称来保存
             第四个参数:
             */
            [formData appendPartWithFileData:data name:@"file" fileName:@"123.png" mimeType:@"image/png"];
            
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            NSLog(@"%f",1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSLog(@"success--%@",responseObject);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"failure -- %@",error);
        }];
    }
    
    

    NSURLSessionConfiguration配置信息

    • 作用:
    • 统一配置session的信息,每个session可以发送多个请求
    • 设置蜂窝网络,隐私信息,超时时间\
    @property (strong, nonatomic) NSURLSession *session;
    //将session设置为全局的属性,方便发送网络请求
    //在懒加载里面设置配置的信息,达到统一设置
    #pragma  makr - 懒加载
    -(NSURLSession *)session
    {
        if (_session == nil) {
            
            //设置配置信息
            NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
            
            //统一设置请求超时
            config.timeoutIntervalForRequest = 15.0;
            //设置是否允许蜂窝网络访问
            config.allowsCellularAccess = YES;
            
            _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
        }
        return _session;
    }
    
    

    AFNetWorking的序列化

    • AFNetWorking默认是JSON解析(因为开发中百分之90都是JSON数据)

    默认情况:JSON AFJSONResponseSerializer
    XML:AFXMLParserResponseSerializer
    既不是XML也不是JSON:AFHTTPResponseSerializer

    • JSON
        //1.创建会话管理者
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        
        /*
         1)afn内部默认已经完成了JSON解析工作
            优点:方便
            缺点:如果服务器返回的数据不是JSON会报错
         */
        NSDictionary *dict = @{@"type":@"JSON"};
        //2.发请求
        [manager GET:@"需要请求的URL" parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            NSLog(@"%@--%@",[responseObject class],responseObject);
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@---",error);
        }];
    
    • XML
    -(void)xml
    {
    <NSXMLParserDelegate>代理协议
    
        //1.创建会话管理者
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        
        //设置以XML的方式来解析数据
        manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
        
        NSDictionary *dict = @{@"type":@"XML"};
        //2.发请求
        [manager GET:@"需要请求的URL" parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            NSLog(@"%@--%@",[responseObject class],responseObject);
            //1.创建解析器
            NSXMLParser *parser = (NSXMLParser *)responseObject;
            
            //2.设置代理
            parser.delegate = self;
            
            //3.开始解析
            [parser parse];
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@---",error);
        }];
    }
    
    • OtherHttpData
    -(void)otherHttpData
    {
        //1.创建会话管理者
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        
        //设置不做处理
        manager.responseSerializer = [AFHTTPResponseSerializer serializer];
        
        //2.发请求
        [manager GET:@"需要请求的URL" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            NSLog(@"%@--%@",[responseObject class],responseObject);
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@---",error);
        }];
    }
    
    #pragma mark NSXMLParserDelegate
    -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict
    {
        NSLog(@"%@--%@",elementName,attributeDict);
    }
    
    • 检测网络的状态
    -(void)networkStatusChangeAFN
    {
        //1.获得一个网络状态监听管理者
       AFNetworkReachabilityManager *manager =  [AFNetworkReachabilityManager sharedManager];
        
        //2.监听状态的改变(当网络状态改变的时候就会调用该block)
        [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            
            /*
             AFNetworkReachabilityStatusUnknown          = -1,  未知
             AFNetworkReachabilityStatusNotReachable     = 0,   没有网络
             AFNetworkReachabilityStatusReachableViaWWAN = 1,    3G|4G
             AFNetworkReachabilityStatusReachableViaWiFi = 2,   WIFI
             */
            switch (status) {
                case AFNetworkReachabilityStatusReachableViaWiFi:
                    NSLog(@"wifi");
                    break;
                case AFNetworkReachabilityStatusReachableViaWWAN:
                    NSLog(@"3G|4G");
                    break;
                case AFNetworkReachabilityStatusNotReachable:
                    NSLog(@"没有网络");
                    break;
                case AFNetworkReachabilityStatusUnknown:
                    NSLog(@"未知");
                    break;
                    
                default:
                    break;
            }
        }];
        
        //3.手动开启 开始监听
        [manager startMonitoring];
    }
    
    
    AFN使用技巧
    1.在开发的时候可以创建一个工具类,继承自我们的AFN中的请求管理者,再控制器中真正发请求的代码使用自己封装的工具类。
    2.这样做的优点是以后如果修改了底层依赖的框架,那么我们修改这个工具类就可以了,而不用再一个一个的去修改。
    3.该工具类一般提供一个单例方法,在该方法中会设置一个基本的请求路径。
    4.该方法通常还会提供对GET或POST请求的封装。
    5.在外面的时候通过该工具类来发送请求
    6.单例方法:+ (instancetype)shareNetworkTools{  
      static XMGNetworkTools *instance;  
      static dispatch_once_t onceToken;    
    dispatch_once(&onceToken, ^{        
    // 注意: BaseURL中一定要以/结尾     
      instance=[[selfalloc]initWithBaseURL:[NSURL URLWithString:@"请求的URL"]];    });    return instance;
    }
     
    
    

    相关文章

      网友评论

      本文标题:iOS9之后AFNetWorking的使用(详细)

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