iOS开发——网络编程OC篇&(十二)AFN详解

AFN详解

众所周知,苹果搞的一套框架NSContention发送请求与接收请求的方式十分繁琐。操作起来很不方便。不仅要做区分各种请求设置各种不同的参数,而且还要经常在多线程里操作,同时还要对请求与返回的数据做各种序列化的操作,同时还要考虑请求数据的安全等一堆问题。


一、早前的几个网络框架
1、ASI框架HTTP终结者.很牛, 但是有BUG, 已经停止更新.
2、MKNetworkKit (印度人写的).
3、AFN一直还在更新.

AFNetworking的出现:MAC/iOS设计的一套网络框架.(为了简化网络操作)

*AFN专注与网络数据传输,以及网络中多线程的处理.

 

二、AFNetworking的使用

1、AFN特性 :
*登录传参数时,传递字典即可.(键名为参数名,键值为参数值).
*自动到子线程中执行,执行完后返回主线程.
*返回的结果自动序列化NSDictionary.

2、使用AFN注意 :
*AFHTTPRequestOperationManager封装了通过HTTP协议与Web应用程序进行通讯的常用方法.(这个实例化的时候不是单例, 因为没有shared)
*包括创建请求/响应序列化/网络监控/数据安全.
*方法等都是AF开头的.

 

3、AFN能做的 (网络中的都涵盖了):
*GET/POST/PUT/DELETE/HEAD请求.
*JSON数据解析/Plist数据解析.(不支持XML数据解析)
*POSTJSON.
*上传/下载.

 

4、使用步骤 : (可参考说明文档)
1.首先需要实例化一个请求管理器AFHTTPRequestOperationManager.
2.设置请求的数据格式:默认是二进制.(不是可改)
*AFHTTPRequestSerializer(二进制)
*AFJSONRequestSerializer(JSON)
*AFPropertyListRequestSerializer(Plist)
3.设置响应的数据格式:默认是JSON.(不是可改)
*AFHTTPResponseSerializer(二进制)
*AFJSONResponseSerializer(JSON)
*AFPropertyListResponseSerializer(Plist)
*AFXMLParserResponseSerializer(XML)
*AFImageResponseSerializer(Image)
*AFCompoundResponseSerializer(组合的)
4.如果响应者的MIMEType不正确,就要修改acceptableContentTypes.
5.调用方法,发送响应的请求(GET/POST...).
 
代码说话:
一:基本请求与使用
  1 - (void)getSession
  2 {
  3     // AFHTTPSessionManager 对 NSURLSession 的封装
  4     AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
  5     [mgr GET:@"" parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
  6         
  7     } failure:^(NSURLSessionDataTask *task, NSError *error) {
  8         
  9     }];
 10 }
 11 
 12 /**
 13  *  利用AFN发送一个POST请求,服务器返回的JSON数据
 14  */
 15 - (void)postJSON
 16 {
 17     // AFHTTPRequestOperationManager 对 NSURLConnection的封装
 18     
 19     // 1.创建一个请求操作管理者
 20     AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
 21     
 22     // 2.请求参数
 23     NSMutableDictionary *params = [NSMutableDictionary dictionary];
 24     params[@"username"] = @"哈哈哈";
 25     params[@"pwd"] = @"123";
 26     
 27     // 3.发送一个GET请求
 28     NSString *url = @"http://localhost:8080/MJServer/login";
 29     [mgr POST:url parameters:params
 30      success:^(AFHTTPRequestOperation *operation, id responseObject) {
 31          // 请求成功的时候调用这个block
 32          NSLog(@"请求成功---%@", responseObject);
 33      } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
 34          // 请求失败的时候调用调用这个block
 35          NSLog(@"请求失败");
 36      }];
 37 }
 38 
 39 /**
 40  *  利用AFN发送一个GET请求,服务器返回的JSON数据,让AFN直接返回data
 41  */
 42 - (void)getData
 43 {
 44     // 1.创建一个请求操作管理者
 45     AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
 46     // 声明:不要对服务器返回的数据进行解析,直接返回data即可
 47     // 如果是文件下载,肯定是用这个
 48     // responseObject的类型是NSData
 49     mgr.responseSerializer = [AFHTTPResponseSerializer serializer];
 50     
 51     // 2.请求参数
 52     NSMutableDictionary *params = [NSMutableDictionary dictionary];
 53     params[@"username"] = @"哈哈哈";
 54     params[@"pwd"] = @"123";
 55     
 56     // 3.发送一个GET请求
 57     NSString *url = @"http://localhost:8080/MJServer/login";
 58     [mgr GET:url parameters:params
 59      success:^(AFHTTPRequestOperation *operation, id responseObject) {
 60          // 请求成功的时候调用这个block
 61          NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableLeaves error:nil];
 62          
 63          NSLog(@"%@", dict);
 64      } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
 65          // 请求失败的时候调用调用这个block
 66          NSLog(@"请求失败");
 67      }];
 68 }
 69 
 70 /**
 71  *  利用AFN发送一个GET请求,服务器返回的XML数据
 72  */
 73 - (void)getXML
 74 {
 75     // 1.创建一个请求操作管理者
 76     AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
 77     // 声明:等会服务器返回的是XML数据
 78     // responseObject的类型是NSXMLParser
 79     mgr.responseSerializer = [AFXMLParserResponseSerializer serializer];
 80     
 81     // 2.请求参数
 82     NSMutableDictionary *params = [NSMutableDictionary dictionary];
 83     params[@"username"] = @"哈哈哈";
 84     params[@"pwd"] = @"123";
 85     params[@"type"] = @"XML";
 86     
 87     // 3.发送一个GET请求
 88     NSString *url = @"http://localhost:8080/MJServer/login";
 89     [mgr GET:url parameters:params
 90      success:^(AFHTTPRequestOperation *operation, id responseObject) {
 91          // 请求成功的时候调用这个block
 92          NSLog(@"请求成功--%@", responseObject);
 93 //         responseObject.delegate = self;
 94 //         [responseObject parse];
 95      } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
 96          // 请求失败的时候调用调用这个block
 97          NSLog(@"请求失败");
 98      }];
 99 }
100 
101 /**
102  *  利用AFN发送一个GET请求,服务器返回的JSON数据
103  */
104 - (void)getJSON
105 {
106     // 1.创建一个请求操作管理者
107     AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
108     // 声明一下:服务器返回的是JSON数据
109     //    mgr.responseSerializer = [AFJSONResponseSerializer serializer];
110     // responseObject的类型是NSDictionary或者NSArray
111     
112     // 2.请求参数
113     NSMutableDictionary *params = [NSMutableDictionary dictionary];
114     params[@"username"] = @"哈哈哈";
115     params[@"pwd"] = @"123";
116     
117     // 3.发送一个GET请求
118     NSString *url = @"http://localhost:8080/MJServer/login";
119     [mgr GET:url parameters:params
120      success:^(AFHTTPRequestOperation *operation, id responseObject) {
121          // 请求成功的时候调用这个block
122          NSLog(@"请求成功---%@", responseObject);
123      } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
124          // 请求失败的时候调用调用这个block
125          NSLog(@"请求失败");
126      }];
127 }

二:文件上传

  1 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
  2 {
  3     UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"请选择图片" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"拍照", @"相册", nil];
  4     [sheet showInView:self.view.window];
  5 }
  6 
  7 #pragma mark - UIActionSheet
  8 - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
  9 {
 10     UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
 11     // 设置代理
 12     ipc.delegate = self;
 13     
 14     switch (buttonIndex) {
 15         case 0: { // 拍照
 16             if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) return;
 17             ipc.sourceType = UIImagePickerControllerSourceTypeCamera;
 18             break;
 19         }
 20         case 1: { // 相册
 21             if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) return;
 22             ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
 23             break;
 24         }
 25         default:
 26             break;
 27     }
 28     
 29     // 显示控制器
 30     [self presentViewController:ipc animated:YES completion:nil];
 31 }
 32 
 33 #pragma mark - UIImagePickerControllerDelegate
 34 /**
 35  *  在选择完图片后调用
 36  *
 37  *  @param info   里面包含了图片信息
 38  */
 39 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
 40 {
 41     // 销毁控制器
 42     [picker dismissViewControllerAnimated:YES completion:nil];
 43     
 44     // 获得图片
 45     UIImage *image = info[UIImagePickerControllerOriginalImage];
 46     
 47     // 显示图片
 48     self.imageView.image = image;
 49 }
 50 
 51 - (void)upload1
 52 {
 53     // 1.创建一个管理者
 54     AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
 55     
 56     // 2.封装参数(这个字典只能放非文件参数)
 57     NSMutableDictionary *params = [NSMutableDictionary dictionary];
 58     params[@"username"] = @"123";
 59     params[@"age"] = @20;
 60     params[@"pwd"] = @"456";
 61     params[@"height"] = @1.55;
 62     
 63     // 2.发送一个请求
 64     NSString *url = @"http://localhost:8080/MJServer/upload";
 65     [mgr POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
 66         // 在发送请求之前会自动调用这个block
 67         // 需要在这个block中添加文件参数到formData中
 68         
 69         /**
 70          FileURL : 需要上传的文件的URL路径
 71          name : 服务器那边接收文件用的参数名
 72          fileName : (告诉服务器)所上传文件的文件名
 73          mimeType : 所上传文件的文件类型
 74          */
 75         NSURL *url = [[NSBundle mainBundle] URLForResource:@"itcast" withExtension:@"txt"];
 76         [formData appendPartWithFileURL:url name:@"file" fileName:@"test.txt" mimeType:@"text/plain" error:nil];
 77         
 78         /**
 79          FileData : 需要上传的文件的具体数据
 80          name : 服务器那边接收文件用的参数名
 81          fileName : (告诉服务器)所上传文件的文件名
 82          mimeType : 所上传文件的文件类型
 83          */
 84         //        UIImage *image = [UIImage imageNamed:@"minion_01"];
 85         //        NSData *fileData = UIImagePNGRepresentation(image);
 86         //        [formData appendPartWithFileData:fileData name:@"file" fileName:@"haha.png" mimeType:@"image/png"];
 87     } success:^(AFHTTPRequestOperation *operation, id responseObject) {
 88         NSLog(@"上传成功");
 89     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
 90         NSLog(@"上传失败");
 91     }];
 92 }
 93 
 94 - (IBAction)upload {
 95     if (self.imageView.image == nil) return;
 96     
 97     // 1.创建一个管理者
 98     AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
 99     
100     // 2.封装参数(这个字典只能放非文件参数)
101     NSMutableDictionary *params = [NSMutableDictionary dictionary];
102     params[@"username"] = @"123";
103     params[@"age"] = @20;
104     params[@"pwd"] = @"456";
105     params[@"height"] = @1.55;
106     
107     // 2.发送一个请求
108     NSString *url = @"http://192.168.15.172:8080/MJServer/upload";
109     [mgr POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
110         NSData *fileData = UIImageJPEGRepresentation(self.imageView.image, 1.0);
111         [formData appendPartWithFileData:fileData name:@"file" fileName:@"haha.jpg" mimeType:@"image/jpeg"];
112 
113         // 不是用这个方法来设置文件参数
114 //        [formData appendPartWithFormData:fileData name:@"file"];
115     } success:^(AFHTTPRequestOperation *operation, id responseObject) {
116         NSLog(@"上传成功");
117     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
118         NSLog(@"上传失败");
119     }];
120     
121     // 文件下载,文件比较大,断点续传技术:普遍所有的HTTP服务器都支持
122     // 文件上传,文件比较大,断点续传技术:一般的HTTP服务器都不支持,常用的技术用的是Socket(TCP\IP、UDP)
123 }
总结:
一、2大管理对象
1.AFHTTPRequestOperationManager
* 对NSURLConnection的封装

2.AFHTTPSessionManager
* 对NSURLSession的封装

二、AFHTTPRequestOperationManager的具体使用
1.创建管理者
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];

2.封装请求参数
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"username"] = @"哈哈哈";
params[@"pwd"] = @"123";

3.发送请求
NSString *url = @"http://localhost:8080/MJServer/login";
[mgr POST:url parameters:params
  success:^(AFHTTPRequestOperation *operation, id responseObject) {
      // 请求成功的时候调用这个block
      NSLog(@"请求成功---%@", responseObject);
  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
      // 请求失败的时候调用调用这个block
      NSLog(@"请求失败");
  }];
// GET请求
[mgr GET:url parameters:params
  success:^(AFHTTPRequestOperation *operation, id responseObject) {
      // 请求成功的时候调用这个block
      NSLog(@"请求成功---%@", responseObject);
  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
      // 请求失败的时候调用调用这个block
      NSLog(@"请求失败");
  }];

三、对服务器返回数据的解析
1.AFN可以自动对服务器返回的数据进行解析
* 默认将服务器返回的数据当做JSON来解析

2.设置对服务器返回数据的解析方式
1> 当做是JSON来解析(默认做法)
* mgr.responseSerializer = [AFJSONResponseSerializer serializer];
* responseObject的类型是NSDictionary或者NSArray
 
 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。