【ios】使用Block對POST異步操作的簡單封裝


以下內容為原創,歡迎轉載,轉載請注明

來自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3409721.html

一般情況下的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下載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM