/*
不是技术性的文章,只是自己记录每天所学的方式。
-----------------------程序员的天空是去往星辰的大海
*/
- 1 - 眼下流行的第三方类库AFNetWorking 作为异步请求方式的一种
与其他两种老版网络请求之间有很大的区别。在此不对NSURLConnection系统类的封装以及更久远的ASI方法做赘述,稍后再开一篇总结这两种方法的学习心得。
此处介绍AFNetingWorking 异步单任务请求和异步多任务请求的两种方式。
1>为什么要使用异步请求
异步请求相对于同步请求数据操作,在用户体验上占有更大的优势。同步数据请求,在请求的数据内容庞大的时候,往往受网速限制严重,系统主线程被数据请求捆绑,无法更好的实现UI加载。
2>AFNetWorking类库的使用方式 直接拖入工程加载即可
-2- AFNetworking的使用
1、AFN特性 :
*登录传参数时,传递字典即可.(键名为参数名,键值为参数值).
*自动到子线程中执行,执行完后返回主线程.
*返回的结果自动序列化为NSDictionary.
2、使用AFN注意 :
*AFHTTPRequestOperationManager封装了通过HTTP协议与Web应用程序进行通讯的常用方法.(这个实例化的时候不是单例, 因为没有shared字)
*包括创建请求/响应序列化/网络监控/数据安全.
*方法等都是以AF开头的.
3、AFN能做的 (网络中的都涵盖了):
*GET/POST/PUT/DELETE/HEAD请求.
*JSON数据解析/Plist数据解析.(现下支持XML数据解析,但解析使用系统类库,sax模式,不推荐使用)
*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...).
-3-两种异步请求的对比
1、AFNetWorking单任务异步请求
1>AFNetWorking 单任务异步GET请求时 使用异步请求操作管理者对象 AFHTTPRequestOperationManager
AFHTTPRequestOperationManager * manager = [AFHTTPRequestOperationManager manager];
2⃣️ 设置请求数据的类型(json 还是Xml)json 使用/text/json xml使用text/xml
manager.responseSerializer.acceptableContentTypes=[NSSet setWithObject:@"application/json"];/
AFNetWorking受欢迎一大原因主要是来自于它的自解析 ,只需要在请求数据类型处设置解析格式,就可以使用该种类型的解析方式。在post
请求时使用的是/text/html。
3⃣️ 开始数据请求并解析
//参数解释 第一个为网络请求地址 第二个是请求体 不用写 第三个为数据处理内容
//请求体内容在GET请求时无需设置,直接设置为nil。在网络请求地址里,要将需要的参数全数使用?username=xxx&password=ooo这样
的方式拼接好。
[manager GET:kJSONUrlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
//json解析
if([responseObject isKindOfClass:[NSDictionary class]]){//json解析出来的返回值为字典类型
NSLog(@"%@",responseObject);
}else if([responseObject isKindOfClass:[NSData class]]){//xml解析出来的结果是NSdata类型
NSLog(@"%@",responseObject);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"error : %@",error);
}];
【特别注意】由于AFNETWorking在进行XML解析时使用的是sax模式,效率低下且速度很慢,一般我们不直接使用该种方法,关闭XML解析的方法
为
manager.responseSerializer = [AFCompoundResponseSerializer serializer];
关闭后使用GData可以使用dom模式来解析XML模式
2>AFNetWorking 单任务异步POST请求时 只需要多设置一下请求体内容即可
parameters:后面的参数为id类型 但一般填写dic类型,dic类型将参数名作为键值,将参数值作为值值来保存。
如
NSDictionary * dict=@{@"username": field1.text,
@"password":field2.text,
@"email":field3.text};
3>AFNetWorking POST传输大量数据的时候,如上传一张照片的data数据
AFHTTPRequestOperationManager * manager=[AFHTTPRequestOperationManager manager];
[manager POST:UPLOADPATH parameters:dic constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
//上传图片的二进制数据
/*
参数解释 1.上传的图片二进制对象 2.参数名称<此处为attach> 3.为图片起一个名字<任意名但不能是中文>
4.此type值是固定 image/png
*/
[formData appendPartWithFileData:imageData name:@"attach" fileName:@"hello.png" mimeType:@"image/png"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"%@",responseObject[@"message"]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"%@",error.description);
}];
2、AFNetWorking 异步多任务请求
//1.str 2.url
NSURL * url =[NSURL URLWithString:URL];
//3.request
NSURLRequest * request=[NSURLRequest requestWithURL:url];
//4将请求对象封装成请求操作对象 区别于单任务
AFHTTPRequestOperation * operation=[[AFHTTPRequestOperation alloc]initWithRequest:request];
//5.开始异步请求操作
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
UIImageView * imageV=(UIImageView *)[self.view viewWithTag:100];
//此处responseObject为data类型的
imageV.image=[UIImage imageWithData:responseObject];
NSLog(@"request");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"error%@",error);
}];
//1.str 2.url
NSURL * url1 =[NSURL URLWithString:URL1];
//3.request
NSURLRequest * request1=[NSURLRequest requestWithURL:url1];
//4将请求对象封装成请求操作对象 区别于昨天
AFHTTPRequestOperation * operation1=[[AFHTTPRequestOperation alloc]initWithRequest:request1];
//5.开始异步请求操作
[operation1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
UIImageView * imageV=(UIImageView *)[self.view viewWithTag:101];
//此处responseObject为data类型的
imageV.image=[UIImage imageWithData:responseObject];
NSLog(@"request1");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"error%@",error);
}];
//1.str 2.url
NSURL * url2 =[NSURL URLWithString:URL2];
//3.request
NSURLRequest * request2=[NSURLRequest requestWithURL:url2];
//4将请求对象封装成请求操作对象 区别于昨天
AFHTTPRequestOperation * operation2=[[AFHTTPRequestOperation alloc]initWithRequest:request2];
//5.开始异步请求操作
[operation2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
UIImageView * imageV=(UIImageView *)[self.view viewWithTag:102];
//此处responseObject为data类型的
imageV.image=[UIImage imageWithData:responseObject];
NSLog(@"request2");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"error%@",error);
}];
------上面创建operation的方法可以循环创建,此处不再赘述------
//6.将多个请求对象放在队列中
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
//7.设置队列中请求对象的个数
queue.maxConcurrentOperationCount = 3;
//8.将所有请求对象存放在队列中
[queue addOperations:@[operation1,operation2,operation] waitUntilFinished:NO];