AFN的简单使用

作者: MiracleGl | 来源:发表于2017-03-06 21:45 被阅读475次

    AFNetworking是一个令人愉快的iOS和Mac OS X的网络库。它建立在基础URL加载系统之上,扩展了Cocoa中内置的强大的高级网络抽象。它有一个模块化架构,设计良好,功能丰富的API,使用起来很方便。

    • AFN的简介
      • 简介
      • 请求数据格式
      • 响应数据格式
      • 数据格式小结
    • AFN模拟登陆
      • 发送GET请求获取普通的Json数据
      • AFN发送GET请求模拟登陆
      • AFN发送POST请求模拟登陆
    • AFN常见错误
    • AFN实现文件上传和下载
      • 文件上传
      • 文件下载
    • AFN常用功能
      • AFN之BaseURL
      • AFN之HTTPS
      • AFN之监测网络环境
    • 封装简单的网络请求工具类

    AFN的简介

    简介
    • 目前国内开发网络应用使用最多的第三方框架
    • 是专为Mac OSiOS设计的一套网络框架
    • NSURLConnectionNSURLSession做了封装
    • 提供有丰富的API
    • 提供了完善的错误解决方案
    • 使用起来相对来说比较简单
    • 官网地址:AFNetworking
    请求数据格式
    • AFURLRequestSerialization

    | 类型 | 说明 |
    | --- | :---: | ---:|
    | AFHTTPRequestSerializer | 二进制的,默认的 |
    | AFJSONRequestSerializer | JSON(POST JSON) RESTful 设计风格需要 |
    | AFPropertyListRequestSerializer | PList(POST Plist-开发中几乎不用) |

    响应数据格式
    • AFURLResponseSerialization

    | 类型 | 说明 |
    | --- | :---: | ---:|
    | AFHTTPResponseSerializer | HTTP二进制的 |
    | AFJSONResponseSerializer | JSON默认的 |
    | AFXMLParserResponseSerializer | XML Parser解析器 SAX解析 |
    | AFXMLDocumentResponseSerializer | (Mac OS X) XML DOM |
    | AFPropertyListResponseSerializer | PList几乎不用 |
    | AFImageResponseSerializer | 图像,不支持GIF |
    | AFCompoundResponseSerializer | 组合的 |

    数据格式小结
    • 大多数情况下,都是JSON格式,不需要指定
    • 如果是XML格式
      • 如果SAX解析,需要指定格式
        • manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
      • 然后利用代理方法解析
      • 如果DOM解析,需要指定格式
        • manager.responseSerializer = [AFHTTPResponseSerializer serializer];
      • 然后利用第三方框架解析
    • 图像
      • AFN支持图像缓存
      • 但是不支持GIF
    • 提示
      • 使用AFN时,一定记住要输出:error

    AFN模拟登陆

    导入头文件:#import "AFNetworking.h

    发送GET请求获取普通的JSON数据
    - (IBAction)demo:(id)sender
    {
        // 1.网络请求地址
        NSString *URLString = @"http://xxxx/demo.json";
    
        // 2.创建网络请求管理者
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
        // 3.发送网络请求
        [manager GET:URLString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    
            NSLog(@"%@ %@",[responseObject class],responseObject);
    
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@",error);
        }];
    }
    
    
    AFN发送GET请求模拟登陆
    - (IBAction)GETLogin:(id)sender {
    
        // NSString *URLString = @"http://xxxx/php/login/login.php?username=zhangsan&password=zhang";
    
        // 登陆地址
        NSString *URLString = @"http://xxxx/php/login/login.php";
    
        // 网络请求管理者
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
        // 请求参数
        NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
        parameters[@"username"] = @"zhangsan";
        parameters[@"password"] = @"zhang";
    
        // 发送GET请求
        [manager GET:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    
            NSLog(@"%@",responseObject);
    
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@",error);
        }];
    }
    
    
    
    AFN发送POST请求模拟登陆
    - (IBAction)POSTLogin:(id)sender {
    
        // 登陆地址
        NSString *URLString = @"http://xxxx/php/login/login.php";
    
        // 网络请求管理者
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
        // 请求参数
        NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
        parameters[@"username"] = @"zhangsan";
        parameters[@"password"] = @"zhang";
    
        // 发送POST请求
        [manager POST:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    
            NSLog(@"%@",responseObject);
    
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@",error);
        }];
    }
    
    

    AFN常见错误

    AFN常见的序列化和反序列化的错误
     1.常见错误一 :
        AFN支持接收 @"application/json", @"text/json", @"text/javascript" 文本类型
        AFN不支持接收 text/html 文本类型
    
     2.常见错误二 :
        AFN默认的成功的回调 responseObject 是把服务器返回的数据当做JSON数据格式解析,返回字典或者数组.
        但是在加载网页数据时,响应体是字符串.需要修改响应的序列化方式,让AFN给我们返回原始的二进制数据即可.
    
     3.常见错误三 :
        AFN不支持接收 text/plian 文本类型
    
     4.常见错误四 :
        AFN默认只支持向服务器发送普通的二进制数据.比如普通的GET和POST请求数据.默认不支持发送JSON数据到服务器
        如果要向服务器发送JSON格式的二进制数据,就需要特殊的处理请求的方式.使AFN支持向服务器发送JSON形式的二进制数据
    
    
    其他常见错误
    • 加载网页数据时
    - (void)loadData
    {
        // 网络请求manager
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
        // 常见错误一 : 修改AFN支持接收的文本类型 : text/html
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];
    
        // 常见错误二 : 修改AFN默认的返回的数据类型,设置默认为只返回原始的二进制数据,程序猿自己解析
        manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
        // 网络请求地址
        NSString *URLStr = @"http://www.baidu.com";
    
        // 发送网络请求
        [manager GET:URLStr parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    
    //        NSLog(@"%@ %@",[responseObject class],responseObject);
    
            NSString *html = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
            NSLog(@"%@",html);
    
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"出错 %@",error);
        }];
    }
    
    
    • 向服务器发送JSON数据时
    - (void)postJSON
    {
        // 网络请求manager
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
        // 常见错误三 : 修改AFN支持接收的文本类型 : text/plian
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", @"text/plain", nil];
    
        // 常见错误二 : 修改AFN默认的返回的数据类型,设置默认为只返回原始的二进制数据,程序猿自己解析
        manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
        // 常见错误四 : 修改AFN支持向服务器发送JSON形式的二进制数据
        manager.requestSerializer = [AFJSONRequestSerializer serializer];
    
        // 网络请求地址
        NSString *URLStr = @"http://localhost/php/upload/postjson.php";
    
        // 请求参数
        NSDictionary *parameters = @{
                                        @"name":@"zhangsan"
                                    };
    
        // 发送网络请求
        [manager POST:URLStr parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    
    //        NSLog(@"%@ %@",[responseObject class],responseObject);
    
            NSString *html = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
            NSLog(@"%@",html);
    
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"出错 %@",error);
        }];
    }
    
    

    AFN实现文件上传和下载

    文件上传
    • 文件数据拼接的方法

      • [formData appendPartWithFileData:data name:@"" fileName:@"" mimeType:@""];
    • 文件数据拼接的四个参数

      • 参数1:上传文件的二进制信息
      • 参数2:服务器接收二进制数据的字段名(跟服务器要)
      • 参数3:文件保存到服务器的名字
      • 参数4:上传的文件的类型
    • 文件上传的主方法

    - (void)uploadFile
    {
        // 网络请求地址
        NSString *URLStr = @"http://xxxx/php/upload/upload-m.php";
    
        // 文件上传的附带信息
        NSDictionary *textDict = @{
                                    @"status":@"zhangsan"
                                   };
    
        // 网络请求manager
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        // 发送POST请求
        [manager POST:URLStr parameters:textDict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
    
            // 获取文件路径1
            NSString *filePath1 = [[NSBundle mainBundle] pathForResource:@"mm01.jpg" ofType:nil];
            NSData *fileData1 = [NSData dataWithContentsOfFile:filePath1];
            // 拼接数据1
            [formData appendPartWithFileData:fileData1 name:@"userfile[]" fileName:[filePath1 lastPathComponent] mimeType:@"image/jpg"];
    
            // 获取文件路径2
            NSString *filePath2 = [[NSBundle mainBundle] pathForResource:@"mm02.jpg" ofType:nil];
            NSData *fileData2 = [NSData dataWithContentsOfFile:filePath2];
            // 拼接数据2
            [formData appendPartWithFileData:fileData2 name:@"userfile[]" fileName:[filePath2 lastPathComponent] mimeType:@"image/jpg"];
    
        } progress:^(NSProgress * _Nonnull uploadProgress) {
    
            NSLog(@"进度 %f",uploadProgress.fractionCompleted);
    
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    
            NSLog(@"%@ %@",[responseObject class],responseObject);
    
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"出错 %@",error);
        }];
    }
    
    
    文件下载
    - (void)downloadFile
    {
        // 下载地址
        NSString *URLString = @"http://xxxx/xcode.zip";
        // 请求
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URLString]];
        // 管理者
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        // 发起下载任务
        NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
    
            NSLog(@"进度 %f",downloadProgress.fractionCompleted);
    
        } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
    
            // AFN提供的文件保存路径,在tmp文件中,下载完成之后就会被删除
            NSLog(@"%@",targetPath);
    
            // 自己获取文件保存的路径
            NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
    
            // 带file:// 协议头
            NSURL *locationURL = [NSURL fileURLWithPath:filePath];
    
            // 把文件缓存路径剪切出去
            return locationURL;
    
        } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
            // 文件最终保存的路径 : 从上面自动剪切过来的
            NSLog(@"%@",filePath.path);
        }];
        // 开启下载任务
        [downloadTask resume];
    }
    
    

    AFN其他常用功能

    AFN之BaseURL
    • 使用场景:设计网络请求工具类时使用
    - (IBAction)baseURL:(id)sender
    {
        AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:@"http://localhost/"]];
    
        [manager GET:@"demo.json" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    
            NSLog(@"%@",responseObject);
    
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@",error);
        }];
    }
    
    

    AFN之HTTPS

    // 允许无效的证书 : 2.5.4 版本之前使用
    manager.securityPolicy.allowInvalidCertificates = YES;
    // 不验证域名 : 2.6.0 版本之后使用
    manager.securityPolicy.validatesDomainName = NO;
    
    
    - (IBAction)HTTPS:(id)sender
    {
        // 创建网络请求mansger
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
        // 允许无效的证书
        // manager.securityPolicy.allowInvalidCertificates = YES;
        // 不验证域名
        manager.securityPolicy.validatesDomainName = NO;
    
        // 修改AFN默认支持接收的文本类型
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html" ,nil];
    
        // 修改AFN默认处理数据的方式 : 设置成只返回原始的二进制数据,程序猿自己反序列化
        manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
        // 网络请求地址
        NSString *URLStr = @"https://www.baidu.com";
    
        [manager GET:URLStr parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    
            // NSLog(@"%@ %@",[responseObject class],responseObject);
    
            // 反序列化
            NSString *html = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
            NSLog(@"%@",html);
    
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"出错 %@",error);
        }];
    }
    
    

    AFN之监测网络环境

    • 程序一启动就开始监测网络环境
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // Override point for customization after application launch.
    
        // 监测网络环境
        AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    
        /*
         status
         AFNetworkReachabilityStatusUnknown          = -1, 不知道监测的是什么
         AFNetworkReachabilityStatusNotReachable     = 0,  没有检测到网络
         AFNetworkReachabilityStatusReachableViaWWAN = 1,  蜂窝网
         AFNetworkReachabilityStatusReachableViaWiFi = 2,  WIFI
         */
        [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            NSLog(@"%zd",status);
        }];
    
        [manager startMonitoring];
    
        return YES;
    }
    
    

    封装简单的网络请求工具类

    新建类 NetworkTool
    • NetworkTool.h
    // 第一步 : 继承自 AFHTTPSessionManager
    @interface NetworkTool : AFHTTPSessionManager
    
    /**
     *  网络请求工具类全局访问点
     *
     *  @return AFHTTPSessionManager的实例
     */
    + (instancetype)sharedNetworkTool;
    
    /**
     *  网络请求工具类GET请求的主方法
     *
     *  @param URLString 请求地址
     *  @param success   成功的回调
     *  @param faile     失败的回调
     */
    - (void)GETWithURLString:(NSString *)URLString success:(void(^)(id responseObject))success faile:(void(^)(NSError *error))faile;
    
    
    • NetworkTool.m
    + (instancetype)sharedNetworkTool
    {
        static NetworkTool *instance;
        
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            
            // 设置相对路径
            NSURL *BaseURL = [NSURL URLWithString:@"http://c.m.163.com/nc/"];
            // 实例化Manager
            instance = [[self alloc] initWithBaseURL:BaseURL];
            
            // 增加AFN支持的文件类型
            instance.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", @"text/plain", nil];
        });
        
        return instance;
    }
    
    // 网络工具类实现GET请求的主方法
    - (void)GETWithURLString:(NSString *)URLString success:(void (^)(id))success faile:(void (^)(NSError *))faile
    {
        [self GET:URLString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            if (success) {
                success(responseObject);
            }
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            if (faile) {
                faile(error);
            }
        }];
    }
    
    

    感谢读到最后的朋友,最后祝大家工作顺利,请点赞支持一下,谢谢!

    相关文章

      网友评论

        本文标题:AFN的简单使用

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