AFNetworking框架使用
2016-03-05 16:33
267 查看
AFNetWorking框架
封装的connection 和session (task 代理).传递completionHandler( access 和error block )默认支持序列化和反序列化json,xml需要自己解析
封装了reachability 判断网络连接;
支持HTTPS;
下载:终端输入 git clone url
论坛 Stack Overflow
AFN的使用
封装NSURLConnection用法
1. 发送GET请求.//请求操作管理器--对NSURLConnection的封装 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager GET:@"http://127.0.0.1/index1.html" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"%@ %@",operation,responseObject); //获取的数据直接进行了反序列化(如果获取的不是json则出错) } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"出错 %@",error); }]; //AFN会自动把字典转换成url后的参数?username=admin&password=123 NSDictionary *params = @{@"username":@"admin",@"password":@"123"}; 把params传给parameters: 参数即可;
2. 发送post请求.
//请求操作管理器--对NSURLConnection的封装 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; //get请求的参数 NSDictionary *params = @{@"username":@"admin",@"password":@"123"}; [manager POST:@"http://127.0.0.1/php/login.php" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"%@ ",responseObject); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"出错 %@",error); }]; //如果上传文件 , 需要文件url路径 NSURL url = [NSBundle mainBundle] URLForResource:@"01.jpg" withExtension:nil]; [manager POST:@"http://127.0.0.1/php/login.php" parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formaData) { //上传文件 ,不用我们拼接字符串 [forData appendParWithFileURL:url name:@"userfile[]" error:nil]; } success:^(AFHTTPRequestOperation * _Nonnull operation, id _Nonnull responseObject) { NSLog(@"%@",responseObject); } failure:^(AFHTTPRequestOperation * _Nullable operation, NSError * _Nonnull error) { NSLog(@"%@",error); }]; }
封装NSURLSession用法
downloadTask下载,获取下载进度.NSProgress *progress = nil; //进度 ,用输出参数获取,使用KVO观察变化 [[[AFHTTPSesionManager manager] downloadTaskWithRequest:request progress:&progress destination: ^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) { // NSLog(@"targetPath -- %@",targetPath); NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename]; NSURL *url = [[NSURL alloc] initFileURLWithPath:path]; //返回要保存文件的路径, 有一点注意的是,本地文件路径,URL转换只能用initFile方法,不然没有file:协议名前缀; return url; } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) { // } ] resume]//开启任务. //观察progress的某个属性fractionCompleted(进度)是否发生变化 [progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:nil]; /***在kvo观察者方法中进行进度变化监听***/观察的属性变动会调用 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { if ([object isKindOfClass:[NSProgress class]]) {//这个方法会监听多个属性,所以判断下是不是我们要监听的. NSLog(@"fractionCompleted : %f",progress.fractionCompleted); //需要回到主线程更新UI 因为 这个方法更 观察属性的赋值设置 在同一线程 NSLog(@"%@",[NSThread currentThread]); } }
新版AFN取消了NSURLConnection的封装;
关于数据的解析
AFN会默认帮我们把获取的数据进行JSON反序列化,但是如果我们获取的不是JSON就会报错.所以我们连接之前,修改默认响应的序列化器;序列化器类型如下:
发送给服务器的数据
AFHTTPRequestSerializer 二进制(默认)
AFJSONRequestSerializer json
AFPropertyListRequestSerializer plist
从服务器接收的数据
AFHTTPResponseSerializer 二进制
◦ AFJSONResponseSerializer json(默认)
◦ AFXMLParserResponseSerializer xmlParser(sax方式解析xml)
◦ AFXMLDocumentResponseSerializer dom解析xml (Mac OS X)
◦ AFPropertyListResponseSerializer plist
◦ AFImageResponseSerializer image
◦ AFCompoundResponseSerializer 组合
修改序列化器代码如下: 在AFHTTPRequestOperationManager初始化时.
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
请求数据的序列化
manager.responseSerializer = [AFJSONResponseSerializer serializer];
返回数据的序列化
注意:
上面的XML序列化器并不是真正的帮我们序列化了,还是需要使用代理方法节点转换.
关于JSON,有的网页内容是JSON,但是content-type却表示html; 使用AFN会解析会报错,这时要进入框架内部更改序列化器的代码.
//解析XML例子 : [manager GET:@"http://127.0.0.1/videos.xml" parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, NSXMLParser *responseObject) { //解析xml responseObject.delegate = self; [responseObject parse]; } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"%@",error); }]; 再调用//NSXMLParser 的多个代理方法 手动解析.
//解决注意问题 2 manager.responseSerializer.acceptableContentTypes =[NSSet setWithObjects:@"application/json", @"text/json", @"text/html", @"text/javascript", nil]; //给acceptable里面添加 @"text/html". 解决.
补充: 网络状态
前面无论上传下载都没有考虑网络状态,实际会进行3G/wifi判断并提醒用户;通常是利用AFNEtworking发送一个URL然后去检测网络状况变化,网络改变后调用相应的网络状态改变方法.示例:
//创建一个用于测试的url NSURL *url=[NSURL URLWithString:@"http://www.apple.com"]; AFHTTPRequestOperationManager *operationManager=[[AFHTTPRequestOperationManager alloc]initWithBaseURL:url]; //根据不同的网络状态改变去做相应处理 [operationManager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { switch (status) { case AFNetworkReachabilityStatusReachableViaWWAN: [self alert:@"2G/3G/4G Connection."]; break; case AFNetworkReachabilityStatusReachableViaWiFi: [self alert:@"WiFi Connection."]; break; case AFNetworkReachabilityStatusNotReachable: [self alert:@"Network not found."]; break; default: [self alert:@"Unknown."]; break; } }]; //开始监控 [operationManager.reachabilityManager startMonitoring]; //pragma mark 网络状态变化提示 -(void)alert:(NSString *)message{ UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:@"System Info" message:message delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles: nil]; [alertView show]; }
相关文章推荐
- 魔道研究
- 我终于深入参与了一个分布式系统了,好多想法不一样了
- [LeetCode]41 第一个缺失的整数
- 位运算:二进制中1的个数
- JavaScript常用代码(不定时更新)
- 网络-NSURLSession应用和原理
- 字符串匹配
- Android面试题搜集
- LeetCode : String to Integer (atoi) [java]
- 关于enum与typedef enum的用法小结
- LeetCode题解--2-Add Two Numbers
- 37. Sudoku Solver *HARD*
- 由SequenceFile.Writer(key,value)谈toString()方法
- 笔记:继承设计的技巧
- C#连接数据库代码(基础)
- NSRULConnection网络应用
- EF(EntityFramework) 的 CodeFirst 使用指南二(基本使用)
- HBase -ROOT-和.META.表结构(region定位原理)
- php编写的抽奖程序中奖概率算法
- 解决Chrome插件安装时出现的“程序包无效”问题