iOS-----使用AFNetworking实现网络通信

使用AFNetworking实现网络通信

AFNetworking可以用于发送HTTP请求,接收HTTP响应,但不会缓存服务器响应,不能执行HTML页面中嵌入的JavaScript代码,

也不会对页面内容进行任何解析、处理,内置支持JSON、Plist属性文件、XML解析。

提交GET请求与提交POST请求

 在需要使用AFNetworking的程序中使用“#import “AFHTTPRequestOperationManager.h””代码导入AFNetworking的头文件即可

  

使用AFNetworking发送请求、接收响应很简单,只要如下几步

1.创建AFHTTPRequestOperationManager对象

2.根据服务器响应内容的不同,为AFHTTPRequestOprationManager对象指定不同的解析器。

该对象默认的解析器要求服务器响应是JSON数据或Plist数据。

如果服务器响应数据是其他格式的,则需要手动设置响应解析器。

3.如果需要发送GET请求,调用AFHTTPRequestOperationManager对象的GET:parameters:success:failure:方法即可;

如果要发送POST请求,调用该对象的POST:parameters:success:failure:方法即可.两个方法都可指定通信成功、通信失败的代码块。

4.在success:参数指定的代码块中处理服务器响应成功的正确数据;在failure:参数指定的代码块中处理服务器响应的错误数据。

代码片段

 1 /*
 2 
 3        为了通过AFNetworking来访问被保护页面,程序同样需要使用AFNetworking来登录系统,
只要应用程序使用同一个AFHTTPRequestOperationManager发送请求,
AFNetworking就会自动维护与服务器之间的Session状态。也就是说,程序第1次使用AFHTTPRequestOperationManager登录系统后,
接下来使用该对象杰克访问被保护页面了。
4 5 */ 6 7 ViewController.m 8 9 @interface ViewController() 10 11 { 12 13 AppDelegate* appDelegate; 14 15 } 16 17 @end 18 19 @implementation ViewController 20 21 - (void)viewDidLoad 22 23 { 24 25 [super viewDidLoad]; 26 27 appDelegate = [UIApplication sharedApplication].delegate; 28 29 } 30 31 - (IBAction)accessSecret:(id)sender 32 33 { 34 35 // 使用AFHTTPRequestOperationManager发送GET请求 36 37 [appDelegate.manager 38 39 GET:@http://192.168.1.88:8888/AFNetworkingServer/secret.jsp 40 41 parameters:nil // 无须指定请求参数 42 43 // 获取服务器响应成功时激发的代码块 44 45 success:^(AFHTTPRequestOperation *operation , id responseObject) 46 47 { 48 49 // 当使用HTTP响应解析器时,服务器响应数据被封装在NSData中 50 51 // 此处将NSData转换成NSString, 并使用UIWebView将响应字符串显示除了出来 52 53 [self.showView loadHTMLString:[[NSString alloc] initWithData: 54 55 responseObject encoding:NSUTF8StringEncoding] baseURL:nil]; 56 57 } 58 59 // 获取服务器响应失败时激发的代码块 60 61 failure:^(AFHTTPRequestOperation *operation, NSError *error) 62 63 { 64 65 NSLog(@”获取服务器响应出错! ”); 66 67 }]; 68 69 } 70 71 @end

     上面程序中应用程序委托的manager代表一个已经初始化完成的AFHTTPRequestOperationManager对象,

需要修改应用程序委托的application:didFinishLaunchingWithOptions:方法,保证在该方法中创建AFHTTPRequestOperationManager对象,

并指定服务器响应的解析器。

 1 - (BOOL)application:(UIApplication*)application
 2 
 3   didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
 4 
 5 {
 6 
 7    // 创建AFHTTPRequestOperationManager对象
 8 
 9    self.manager = [AFHTTPRequestOperationManager  manager];
10 
11    // 为AFHTTPRequestOperationManager对象指定使用HTTP响应解析器
12 
13    self.manager.responseSerializer = [[AFHTTPResponseSerializer  alloc] init];
14 
15    return YES;
16 
17 }
18 
19 /*
20 
21      创建了一个AFHTTPRequestOperationManager对象,接下来为该对象指定使用AFHTTPResponseSerializer响应解析器,
负责解析服务器响应的HTML数据,当使用这种响应解析器时,代表服务器响应的对象是NSData类型的数据..
22 23 */
  1 LoginController.m
  2 
  3 @interface LoginController()
  4 
  5 {
  6 
  7    AppDelegate*  appDelegate;
  8 
  9 }
 10 
 11 @end
 12 
 13 @implementation LoginController
 14 
 15 - (void)viewDidLoad
 16 
 17 {
 18 
 19    [super viewDidLoad];
 20 
 21    appDelegate = [UIApplication sharedApplication].delegate;
 22 
 23 }
 24 
 25 - (IBAction)loginBnClicked:(id)sender
 26 
 27 {
 28 
 29 //  获取用户输入的用户名和密码
 30 
 31 NSString* name = self.nameFiled.text;
 32 
 33 NSString* pass = self.passField.text;
 34 
 35 if(name != nil && name.length > 0)
 36 
 37 {
 38 
 39    // 使用NSDictionary封装请求参数
 40 
 41   NSDictionary* params = @{@”name”: name , @”pass”: pass};
 42 
 43   //  使用AFHTTPRequestOperationManager发送POST请求
 44 
 45  [appDelegate.manager
 46 
 47    POST:@http://192.168.1.88:8888/AFNetworkingServer/login.jsp
 48 
 49    parameters:params // 指定请求参数
 50 
 51    //  获取服务器响应成功时激发的代码块
 52 
 53   success:^(AFHTTPRequestOperation * operation,  id  responseObject)
 54 
 55 {
 56 
 57     // 当使用HTTP响应解析器时,服务器响应数据被封装在NSData中
 58 
 59    // 此处将NSData转换成NSString,并使用UIAlertView显示登录结果
 60 
 61    [[[UIAlertView  alloc] initWithTitle:@” 登录结果 ”  message:
 62 
 63    [[NSString alloc] initWithData:responseObject  encoding:
 64 
 65      NSUTF8StringEncoding]
 66 
 67     delegate:self  cancelButtonTitle:@”确定”  otherButtonTitles:nil]
 68 
 69     show];
 70 
 71 }
 72 
 73 // 获取服务器响应失败时激发的代码块
 74 
 75     failure:^(AFHTTPRequestOperation  *operation,  NSError *error)
 76 
 77    {
 78 
 79     NSLog(@” 获取服务器响应出错!  ”);
 80 
 81    }];
 82    } 
 85 }
 86 
 87 - (IBAction)finishEdit:(id)sender
 88 
 89 {
 90 
 91     [sender  resignFirstResponder];
 92 
 93 }
 94 
 95 @end
 96 
 97 /*
 98 
 99 上面的红色字代码使用应用程序委托的manager属性(AFHTTPRequestOperationManager对象)的POST方法来发送POST请求,
并使用UIAlertView显示服务器响应.
100 101 如果用户名、密码正确,即可看到登录成功的提示. 102 103 登录成功后,AFHTTPRequestOperationManager将会自动维护与服务器之间的连接,并维护与服务器之间的Session状态,
再次单击“访问页面”按钮。
104 105 使用AFHTTPRequestOperationManager发送GET请求即可正常访问被保护资源,这就是因为前面使用了
AFHTTPRequestOperationManager登录系统,
而且AFHTTPRequestOperationManager可以维护与服务器之间的Session连接。
106 107 */

处理JSON或Plist响应

 AFHTTPRequestOperationManager默认就可以处理JSON或Plist响应。服务器响应数据的MIME(多用途因特网邮件扩展

(Multipurpose Internet Mail Extensions))类型是application/json、text/json(这两个代表JSON响应)、

application/x-plist(Plist响应)其中之一时,AFHTTPRequestOperationManager默认就可以处理,

无须指定服务器响应解析器。

当服务器响应数据是JSON或Plist数据,并且AFHTTPRequestOperationManager成功解析得到服务器响应时,

服务器响应数据以NSArray或NSDictionary形式返回.

/*

   第1个UITableViewController对应的视图控制器类为AuthorsController,该视图控制器类将会向服务器发送GET请求,

服务器响应返回JSON格式数据.该视图控制器将把JSON响应转换为NSArray集合,并使用UITableView显示该NSArray集合数据.

下面是该视图控制器类的实现部分代码.

*/

  1 AuthorsController.m
  2 
  3 @interface AuthorsController()
  4 
  5 {
  6 
  7    NSArray* authors;
  8 
  9    AppDelegate*  appDelegate;
 10 
 11 }
 12 
 13 @end
 14 
 15 @implementation AuthorsController
 16 
 17 - (void)viewDidLoad
 18 
 19 {
 20 
 21 [super  viewDidLoad];
 22 
 23 appDelegate = [UIApplication  sharedApplication].delegate;
 24 
 25 NSString*  url = @”http://192.168.1.88:8888/AFNetworkingServer/authors.json”;
 26 
 27 //  使用AFHTTPRequestOperationManager发送GET请求
 28 
 29 [appDelegate.manager GET:url  parameters:nil
 30 
 31 //获取服务器响应成功时激发的代码块
 32 
 33 success:^(AFHTTPRequestOperation*  operation,  id  responseObject)
 34 
 35 {
 36 
 37    // 将服务器响应的JSON数据转换为Objective-C对象,赋值给authors属性
 38 
 39    authors = responseObject;
 40 
 41   //  重新加载表格数据
 42 
 43  [self.tableView  reloadData];
 44 
 45 }
 46 
 47 //  获取服务器响应失败时激发的代码块
 48 
 49 failure:^(AFHTTPRequestOperation *operation ,  NSError  *error)
 50 
 51 {
 52 
 53    NSLog(@” 获取作者信息出现错误: %@ ”,  error);
 54 
 55 }
 56 
 57   ];
 58 
 59 }
 60 
 61 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
 62 
 63 {
 64 
 65    UITableViewCell* cell = (UITableViewCell*)sender;
 66 
 67    // 获取激发跳转的单元格所在的NSIndexPath
 68 
 69    NSIndexPath* indexPath = [self.tableView indexPathForCell:cell];
 70 
 71   //  获取即将跳转的目标视图控制器
 72 
 73   BooksController*  booksController = (BooksController*)segue.destinationViewController;
 74 
 75   //  将用户选中的单元格的作者信息传给目标视图控制器
 76 
 77   booksControlle.selectedAuthor = [authors  objectAtIndex:indexPath.row]; //
 78 
 79 }
 80 
 81 //  省略UITableViewDataSources协议中的两个方法
 82 
 83 …..
 84 
 85 @end
 86 
 87 /*
 88 
 89     上面的红色字代码发送GET请求时没有指定请求参数,当服务器响应是JSON数据或Plist数据时,服务器响应将被解析成NSArray或NSDictionary对象
---------这取决于服务器响应数据.
90 91 */ 92 93 /* 94 95 显示图书列表的视图控制器类将会向服务器发送POST请求,并将作者ID作为参数发送给服务器,从而获取指定作者对应的图书列表. 96 97 显示图书列表的视图控制器类的实现部分代码 98 99 */ 100 101 BooksController.m 102 103 @interface BooksController() 104 105 { 106 107 NSArray* books; 108 109 AppDelegate* appDelegate; 110 111 } 112 113 @end 114 115 @implementation BooksController 116 117 - (void)viewDidLoad 118 119 { 120 121 [super viewDidLoad]; 122 123 appDelegate = [UIApplication sharedApplication ].delegate; 124 125 NSString* url = @”http://192.168.1.88:8888/AFNetworkingServer/books.json”; 126 127 self.navigationItem.title = [NSString stringWithFormat:@”%@的图书”, 128 129 [self.selectedAuthor objectForKey:@”name”]]; 130 131 // 使用NSDictionary封装请求参数 132 133 NSDictionary* parameters = @{@”authorId”: [self.selectedAuthor objectForKey:@”id”]}; 134 135 // 使用AFHTTPRequestOperationManager发送GET请求 136 137 [ appDelegate.manager POST:url parameters:parameters 138 139 // 获取服务器响应成功时激发的代码块 140 141 success:^(AFHTTPRequestOperation* operation, id responseObject) 142 143 { 144 145 // 将服务器响应的JSON数据转换为Objective-C对象,赋值给books属性 146 147 books = responseObject; 148 149 // 重新加载表格数据 150 151 [self.tableView reloadData]; 152 153 } 154 155 // 获取服务器响应失败时激发的代码块 156 157 failure:^(AFHTTPRequestOperation *operation, NSError * error) 158 159 { 160 161 NSLog(@” 获取图书信息初心错误: %@”, error); 162 163 }]; 164 165 } 166 167 // 省略UITableViewDataSources协议中的两个方法 168 169 …… 170 171 @end 172 173 /* 174 175 上面的红色字代码发送POST请求时指定了请求参数:将作者ID作为参数发送到服务器,当服务器响应是JSON数据或Plist数据时,
服务器响应将被解析成NSArray或NSDictionary对象--------这取决于服务器响应的数据。
176 177 */

服务器使用JSON格式的数据,主要基于如下两个理由

         JSON格式是一种跨语言(几乎所有语言都支持JSON格式)的数据交换格式,而Plist的影响面就小多了。

         Plist格式的本质依然是XML,因此Plist格式的数据在网络上的传输量更大。

处理XML响应

当服务器响应是XML数据时,AFNetworking必须正常处理服务器响应的XML数据,此时则需要为AFHTTPRequestOperationManager显示指定使用AFXMLParserResponseSerializer响应解析器,当使用AFXMLParserResponseSerializer解析器时,服务器返回的数据是一个NSXMLParser对象----

---可通过该对象来解析得到服务器响应的数据.

当服务器响应是XML数据时,使用AFNetworking发送请求后得到的响应是NSXMLParser对象,因此此时必须为NSXMLParser指定delegate来解析服务

器响应的XML数据.

  1 @interface AuthorsController () <NSXMLParserDelegate>
  2 
  3 {
  4 
  5    AppDelegate* appDelegate;
  6 
  7    NSMutableArray* authors;
  8 
  9    NSMutableDictionary* author;
 10 
 11    NSString*  currentTagValue;
 12 
 13 }
 14 
 15 @end
 16 
 17 @implementation  AuthorsController
 18 
 19 - (void)viewDidLoad
 20 
 21 {
 22 
 23    [super  viewDidLoad];
 24 
 25    appDelegate = [UIApplication  sharedApplication].delegate;
 26 
 27    NSString*  url = @”http://192.168.1.88:8888/AFNetworkingServer/authors.xml”;
 28 
 29  //  使用AFHTTPRequestOperationManager发送GET请求   ①
 30 
 31     [appDelegate.manager  GET:url  parameters:nil
 32 
 33 //  获取服务器响应成功时激发的代码块
 34 
 35    success:^(AFHTTPRequestOperation* operation,  id  responseObject)
 36 
 37 {
 38 
 39    // 获取服务器响应的XML数据,并使用NSXMLParser解析该XML数据
 40 
 41   NSXMLParser* parser = responseObject;
 42 
 43   //  指定解析器的delegate是该控制器本身
 44 
 45   parser.delegate = self;
 46 
 47  //  解析服务器响应的XML数据
 48 
 49  [parser  parse];
 50 
 51 // 重新加载表格数据
 52 
 53  [self.tableView  reloadData];
 54 
 55 }
 56 
 57 // 获取服务器响应失败时激发的代码块
 58 
 59 failure:^(AFHTTPRequestOperation*  operation, NSError*  error)
 60 
 61 {
 62 
 63    NSLog(@” 获取作者信息出现错误:  %@” , error);
 64 
 65 }];
 66 
 67 }
 68 
 69 - (void)prepareForSegue:(UIStoryboardSegue *)segue  sender:(id)sender
 70 
 71 {
 72 
 73    UITableViewCell* cell = (UITableViewCell*)sender;
 74 
 75    // 获取激发跳转的单元格所在的NSIndexPath
 76 
 77   NSIndexPath*  indexPath = [self.tableView  indexPathForCell:cell];
 78 
 79   // 获取即将跳转到的目标视图控制器
 80 
 81   BooksController* booksController  = (BooksController*)segue.destinationViewController;
 82 
 83   //  将用户选中的单元格的作者信息传给目标视图控制器
 84 
 85   booksController.selecterAuthor = [authors  objectAtIndexPath.row];
 86 
 87 }
 88 
 89 // 省略UITableViewDataSource协议中的两个方法
 90 
 91 ……
 92 
 93 // 当开始处理某个元素时触发该方法
 94 
 95 - (void)parser: (NSXMLParser*)parser  didStartElement:(NSString*)elementName
 96 
 97   namespaceURI:(NSString *)namespaceURI qualifiedName: (NSString*)qName
 98 
 99   attributes: (NSDictionary*)attributeDict  // ②
100 
101 {
102 
103    if([elementName  isEqualToString:@”authors”])
104 
105    {
106 
107       // 如果正在处理根元素,在此处初始化存储解析结果的NSMutableArray集合
108 
109      authors = [[NSMutableArray alloc] init];
110 
111 }
112 
113 // 如果正在处理<author…/>元素
114 
115  else if([elementName  isEqualToString:@”author”])
116 
117 {
118 
119    // 初始化NSMutableDictionary对象
120 
121   author = [[NSMutableDictionary  alloc]  init];
122 
123 }
124 
125 }
126 
127 //  当开始处理字符串内容时触发该方法
128 
129 //  ③
130 
131 - (void)parser:(NSXMLParser*)parser  foundCharacters: (NSString*)string
132 
133 {
134 
135 //  如果当前的字符串值不为nil,则保存当前正在处理的元素的值
136 
137 if(string)
138 
139 {
140 
141    currentTagValue = string;
142 
143 }
144 
145 }
146 
147 // 当处理某个元素结束时触发该方法
148 
149 - (void)parser: (NSXMLParser*)parser  didEndElement: (NSString*)elementName
150 
151    namespaceURI: (NSString*)namespaceURI  qualifiedName: (NSString*)qName
152 
153 {
154 
155 // 如果处理根元素结束,则表明XML文档处理完成
156 
157 if([elementName  isEqualToString:@”authors”])
158 
159 {
160 
161     return;
162 
163 }
164 
165 //  如果处理<author…/>元素结束,则将封装的NSDictionary对象添加到NSMutableArray集合中
166 
167 else if([elementName  isEqualToString:@”author”])
168 
169 {
170 
171    [author  addObject:author];
172 
173    author = nil;
174 
175 }
176 
177 else
178 
179 {
180 
181    //  如果既不是处理<authors…/>元素,也不是处理<author…/>元素
182 
183    //  使用KVC方式为当前NSDictionary对象添加key-value对
184 
185   [author  setValue:currentTagValue  forKey: elementName];
186 
187    currentTagValue  = nil;
188 
189 }
190 
191 }
192 
193 @end

 从上面的红色字代码不难看出,当服务器响应时XML数据时,AFNetworking发送GET请求、POST请求得到的都是NSXMLParser,程序可通过该对象来解析服务器响应的XML数据------解析服务器数据时,需要自己实现NSXMLParserDelegate协议中的方法来获取服务器响应的XML数据,这样导致编程很麻烦。上面程序中的红色字代码将NSXMLParser的delegate指定为该协议中特定的方法-----------上面程序中的最后3个红色字方法就是为解析XML数据准备的.

上传文件

使用AFNetworking上传文件直接调用AFHTTPRequestOperationManager的POST:parameters:constructingBodyWithBlock:

success:failure:方法提交POST请求即可,该方法比发送普通POST请求的方法多了第3个参数,该参数是一个带AFMultipartFormData

形参的代码块-----可以在该代码块中通过AFMultipartFormData来封装要上传的文件。

AFMultipartFormData提供了如下常用方法:

-  appendPartWithFileURL:name:error:

将指定NSURL对应文件封装成上传文件

-  appendPartWithFileURL:name:fileName:mimeType:error:

将指定NSURL对应文件封装成上传文件.该方法可指定更多选项

-  appendPartWithInputStream:name:fileName:length:mimeType:

将指定输入流中的数据封装成上传文件.该方法可指定更多选项.

-   appendPartWithFileData:name:fileName:mimeType:

将指定NSData代表的数据封装成上传文件.该方法可指定更多选项.

代码片段

  1   /*
  2 
  3     下面程序使用一个UIPickerView来显示用户想要上传的文件,当用户选中某个文件并单击”上传”按钮后,
程序将使用AFHTTPRequestOperationManager发送上传文件的POST请求,从而将图片上传远程服务器(同样需要服
务器有对应的程序来处理文件上传的请求)。
4 5 */ 6 7 ViewController.m 8 9 @interface ViewController() 10 11 { 12 13 AppDelegate* appDelegate; 14 15 NSArray* images; 16 17 } 18 19 @end 20 21 @implementation ViewController 22 23 - (void)viewDidLoad 24 25 { 26 27 [super viewDidLoad]; 28 29 appDelegate = [UIApplication sharedApplication].delegate; 30 31 self.picker.dataSource = self; 32 33 self.picker.delegate = self; 34 35 // 使用简化语法创建NSArray集合 36 37 images = @[@”logo”, @”java”, @”android”]; 38 39 } 40 41 // UIPickerViewDataSource中定义的方法,该方法返回值决定该控件包含多少列 42 43 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView 44 45 { 46 47 // 返回1表明该控件只包含1列 48 49 return 1; 50 51 } 52 53 - (NSInteger)pickerView: (UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component 54 55 { 56 57 return images.count; 58 59 } 63 #define kImageTag 1 64 65 - (UIView *)pickerView: (UIPickerView *)pickerView viewForRow: (NSInteger)row
forComponent: (NSInteger)component reusingView: (UIView*)view 66 67 { 68 69 // 如果可重用的view的tag不等于kImageTag,则表明该View已经不存在,需要重新创建 70 71 if(view.tag != kImageTag) 72 73 { 74 75 view = [[UIView alloc] init]; 76 77 // 为该UIView设置tag属性 78 79 view.tag = kImageTag; 80 81 // 设置不允许用户交互 82 83 view.userInteractionEnabled = NO; 84 85 UIImageView* iv = [[UIImageView alloc] initWithImage: 86 87 [UIImage imageNamed:[images objectAtIndex:row ] ]]; 88 89 iv.frame = CGRectMake(20, 20 , 48, 48); 90 91 iv.contentMode = UIViewContentModeScaleAspectFit; 92 93 [view addSubview:iv]; 94 95 } 96 97 return view; 98 99 } 100 101 // 省略UIPickeViewDataSourceUIPickerViewDelegate协议中的方法 102 103 …… 104 105 - (IBAction)upload: (id)sender 106 107 { 108 109 // 获取用户选中的行 110 111 NSInteger selectedRow = [self.picker selectedRowInComponent: 0]; 112 113 // 获取用户选中的文件名 114 115 NSString* filename = [images objectAtIndex: selectedRow]; 116 117 // 根据用户选中的文件名确定需要上传的文件 118 119 NSURL * filePath = [ [NSBundle mainBundle] URLForResource: filename 120 121 withExtension: @”png”]; 122 123 NSDictionary* parameters = @{@”name”: @”额外的请求参数”}; 124 125 // 使用AFHTTPRequestOperationManager 发送POST请求 126 127 [appDelegate.manager 128 129 POST:@http://192.168.1.88:8888/AFNetworkingServer/upload 130 131 parameters: parameters 132 133 // 使用代码来封装要上传的文件数据 134 135 constructingBodyWithBlock: ^(id<AFMultipartFormData> formData) 136 137 { 138 139 [formData appendPartWithFileURL:filePath // 指定上传文件 140 141 name: @”file” // 指定上传文件对应的请求参数名 142 143 // 指定上传文件的原始文件名 144 145 fileName: [NSString stringWithFormat : @”%@.png “, fileName ] 146 147 // 指定上传文件的MIME类型 148 149 mimeType : @”image/png” 150 151 error: nil ]; 152 153 } 154 155 // 获取服务器响应成功时激发的代码块 156 157 success : ^(AFHTTPRequestOperation* operation, id responseObject) 158 159 { 160 161 // 当使用HTTP响应解析器时, 服务器响应数据被封装在NSData中 162 163 // 此处将NSData转换成NSString, 并使用UIAlertView显示登录结果 164 165 [[[UIAlert alloc] initWithTitle: @” 登录结果 ” message: 166 167 [[NSString alloc] initWithData:responseObject encoding: 168 169 NSUTF8StringEncoding ] delegate: self 170 171 cancelButtonTitle:@” 确定 ” otherButtonTitles: nil ] 172 173 show ]; 174 175 } 176 177 // 获取服务器响应失败时激发的代码块 178 179 failure: ^(AFHTTPRequestOperation* operation, NSError* error) 180 181 { 182 183 NSLog(@” 获取服务器响应出错! ”); 184 185 }]; 186 187 } 188 189 @end

    该程序的关键在于红色字代码块,该代码块位于AFHTTPRequestOperationManager发送POST请求的方法中,该代码块使用AFMultipartFormData的方法

把用户选中的文件封装成上传文件,随着POST请求提交给远程服务器-----远程服务器会处理用户上传的文件.

原文地址:https://www.cnblogs.com/congli0220/p/5072957.html