【ios】使用Block对POST异步操作的简单封装


一般情况下的POST异步操作需要实现以下几步:

1. 在controller.h上实现<NSURLConnectionDataDelegate>协议

2. 实现协议的几个方法,

  • (void)connection:(NSURLConnection )connection didReceiveResponse:(NSURLResponse )response

  • (void)connection:(NSURLConnection )connection didReceiveData:(NSData )data

  • (void)connectionDidFinishLoading:(NSURLConnection *)connection

3. 编写执行post请求的代码:


1 NSURL url = [NSURL URLWithString:urlStr]; // 生成NSURL对象
2 // 生成Request请求对象(并设置它的缓存协议、网络请求超时配置)
3 NSMutableURLRequest
request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
4
5 [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]]; // 设置请求参数
6
7 // 执行请求连接
8 NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:executorDelegate];

 

如果controller有很多异步操作,处理就会很麻烦,而且,很多时候我们只需要处理完成和异常(比如超时)的时候的反馈即可

所以,我需要编写一个post请求的封装类,只要传入请求的url、请求参数(字符串形式)、完成时的回调block

首先,新建类:HttpPostExecutor,.h如下:


 1 //
2 // HttpPostExecutor.h
3 // HttpTest
4 //
5 // Created by WANGJIE on 13-11-6.
6 // Copyright (c) 2013年 WANGJIE. All rights reserved.
7 //
8
9 #import <Foundation/Foundation.h>
10
11 @interface HttpPostExecutor : NSObject<NSURLConnectionDataDelegate>
12 {
13 NSMutableData resultData; // 存放请求结果
14 void (^finishCallbackBlock)(NSString
); // 执行完成后回调的block
15
16 }
17 @property NSMutableData resultData;
18 @property(strong) void (^finishCallbackBlock)(NSString
);
19
20 + (void)postExecuteWithUrlStr:(NSString )urlStr Paramters:(NSString )params FinishCallbackBlock:(void (^)(NSString *))block;
21
22 @end

 

实现了<NSURLConnectionDataDelegate>协议,因为它要接收post请求的几个回调。

有一个NSMutableData对象,这个对象用于储存请求的结果。

一个finishCallbackBlock的block,这个block用于执行完成后的回调,这个block传入的参数就是返回的结果(这个结果已转成utf-8编码的字符串形式),我们可以在这个block中去处理请求完成后的逻辑

还有一个类方法,这个类方法暴露给外面,让外面进行调用

 

接下来,我们看下实现的方法.m文件:



  1 //
2 // POST异步请求的封装
3 // 使用方法,只需传入url,参数组成的字符串,执行完成后的回调block
4 // 如下:
5 // [HttpPostExecutor postExecuteWithUrlStr:@”http://www.baidu.com
6 // Paramters:@””
7 // FinishCallbackBlock:^(NSString result){ // 设置执行完成的回调block
8 // NSLog(@”finish callback block, result: %@”, result);
9 // }];
10 // post提交的参数,格式如下:
11 // 参数1名字=参数1数据&参数2名字=参数2数据&参数3名字=参数3数据&…
12 //
13 //
14 // HttpPostExecutor.m
15 // HttpTest
16 //
17 // Created by WANGJIE on 13-11-6.
18 // Copyright (c) 2013年 WANGJIE. All rights reserved.
19 //
20
21 #import HttpPostExecutor.h
22
23 @implementation HttpPostExecutor
24 @synthesize resultData, finishCallbackBlock;
25
26 /
27 执行POST请求
28 /
29 + (void)postExecuteWithUrlStr:(NSString )urlStr Paramters:(NSString )params FinishCallbackBlock:(void (^)(NSString ))block
30 {
31 // 生成一个post请求回调委托对象(实现了<NSURLConnectionDataDelegate>协议)
32 HttpPostExecutor executorDelegate = [[HttpPostExecutor alloc] init];
33 executorDelegate.finishCallbackBlock = block; // 绑定执行完成时的block
34
35
36 NSURL
url = [NSURL URLWithString:urlStr]; // 生成NSURL对象
37 // 生成Request请求对象(并设置它的缓存协议、网络请求超时配置)
38 NSMutableURLRequest request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
39
40 [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]]; // 设置请求参数
41
42 // 执行请求连接
43 NSURLConnection
conn = [[NSURLConnection alloc] initWithRequest:request delegate:executorDelegate];
44
45 NSLog(conn ? @”连接创建成功 : @”连接创建失败);
46
47 }
48
49
50 /
51 接收到服务器回应的时回调
52 /
53 - (void)connection:(NSURLConnection )connection didReceiveResponse:(NSURLResponse )response
54 {
55 NSHTTPURLResponse resp = (NSHTTPURLResponse )response;
56 // 初始化NSMutableData对象(用于保存执行结果)
57 if(!resultData){
58 resultData = [[NSMutableData alloc] init];
59 }else{
60 [resultData setLength:0];
61 }
62
63 if ([response respondsToSelector:@selector(allHeaderFields)]) {
64
65 NSDictionary dictionary = [resp allHeaderFields];
66
67 NSLog(@”[network]allHeaderFields:%@,[dictionary description]);
68 }
69
70 }
71 /

72 接收到服务器传输数据的时候调用,此方法根据数据大小执行若干次
73 /
74 - (void)connection:(NSURLConnection )connection didReceiveData:(NSData )data
75 {
76 [resultData appendData:data]; // 追加结果
77 }
78 /

79 数据传完之后调用此方法
80 /
81 - (void)connectionDidFinishLoading:(NSURLConnection )connection
82 {
83 // 把请求结果以UTF-8编码转换成字符串
84 NSString resultStr = [[NSString alloc] initWithData:[self resultData] encoding:NSUTF8StringEncoding];
85
86 if (finishCallbackBlock) { // 如果设置了回调的block,直接调用
87 finishCallbackBlock(resultStr);
88 }
89
90
91 }
92 /

93 网络请求过程中,出现任何错误(断网,连接超时等)会进入此方法
94 /
95 - (void)connection:(NSURLConnection )connection didFailWithError:(NSError *)error
96 {
97 NSLog(@”network error: %@, [error localizedDescription]);
98
99 if (finishCallbackBlock) { // 如果设置了回调的block,直接调用
100 finishCallbackBlock(nil);
101 }
102
103
104 }
105 @end


View Code

在这个实现类中,我们在类方法中,先生成一个HttpPostExecutor对象,这个对象用于post请求的回调(因为实现了<NSURLConnectionDataDelegate>协议),然后去执行post连接。

接下来就等下面实现的回调方法被自动调用了,一旦调用

  • (void)connection:(NSURLConnection )connection didReceiveResponse:(NSURLResponse )response

这个方法,就对resultData(用于存储post请求结果)进行初始化或者清空,因为要开始真正存储数据了嘛;

 

  • (void)connection:(NSURLConnection )connection didReceiveData:(NSData )data

这个方法进行回调的时候,把返回过来的这部分数据存储到resultData中,没什么好说的;

 

一旦回调- (void)connectionDidFinishLoading:(NSURLConnection *)connection这个方法,说明数据传输完毕了,要做的逻辑就是把数据转成utf-8编码的字符串,然后回调我们设置的回调finishCallbackBlock,把转好的结果字符串传进去,这样我们在回调block方法中实现的逻辑就能正常执行了。

 

一旦回调- (void)connection:(NSURLConnection )connection didFailWithError:(NSError )error这个方法,说明请求过程中出错了,比如断电、超时等,这时候,也回调我们设置的回调finishCallbackBlock,nil作为结果,这样我们在finishCallbackBlock中就能判断是正常的执行了post还是出了问题。

 

好了,接下来,我们就可以在外面去调用了,如下:


1 [HttpPostExecutor postExecuteWithUrlStr:@”http://www.baidu.com
2 Paramters:@””
3 FinishCallbackBlock:^(NSString *result){
4 // 执行post请求完成后的逻辑
5 NSLog(@”finish callback block, result: %@, result);
6 }];

这样,以后post请求只需要去调用上面这个方法,在回调block中去处理结果

之后,在我们的代码编写中,就可以只关心业务逻辑,不需要去在意请求协议和回调了

 

测试demo下载

 



来源博客:Wang Jie's Blog's Blog
本文链接:https://blog.wangjiegulu.com/2013/11/06/【ios】使用Block对POST异步操作的简单封装/
版权声明:本博客所有文章除特别声明外,均采用 CC BY 4.0 CN协议 许可协议。转载请注明出处。