iOS開發網絡篇—簡單介紹ASI框架的使用
說明:本文主要介紹網絡編程中常用框架ASI的簡單使用。
一、ASI簡單介紹
ASI:全稱是ASIHTTPRequest,外號“HTTP終結者”,功能十分強大。
ASI的實現基於底層的CFNetwork框架,因此運行效率很高。可惜作者早已停止更新,有一些潛在的BUG無人去解決
ASI的github地址
https://github.com/pokeb/asi-http-request
ASI的使用參考
http://www.cnblogs.com/dotey/archive/2011/05/10/2041966.html
http://www.oschina.net/question/54100_36184
二、ASI的使用
1導入
下載並導入ASI框架,注意該框架依賴於Reachability.
導入框架后,如果編譯的話會出現一大堆的錯誤。其中一個最主要的原因是因為該框架是非ARC的。
思考:如果一個框架,其中很多文件都是非ARC的,那么應該如何進行設置?
在這里,介紹最傻瓜的一種方法,通過進行如下的一些設置以解決問題。(
注意:對於所有的asi框架中得文件都需要進行此番設置)

設置完成后,還存在一些錯誤。產生這些錯誤的原因是ASI框架它依賴於下面的幾個框架,把需要的框架添加后再編譯,就不會有問題了。

添加依賴的框架:

把所需的三個框架逐個添加到項目中

2發送網絡請求(同步和異步*GET和POST請求)
示例程序代碼:
1 #import "YYViewController.h" 2 #import "ASIHTTPRequest.h" 3 #import "ASIFormDataRequest.h" 4 5 @interface YYViewController ()<ASIHTTPRequestDelegate> 6 @property(nonatomic,strong)ASIHTTPRequest *request; 7 8 @end 9 10 @implementation YYViewController 11 12 - (void)viewDidLoad 13 { 14 [super viewDidLoad]; 15 } 16 17 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 18 { 19 //同步請求 20 // [self sync]; 21 //異步請求 22 // [self async1]; 23 24 [self post]; 25 } 26 27 #pragma mark-發送post請求 28 -(void)post 29 { //1.創建網絡請求(POST) 30 NSURL *url=[NSURL URLWithString:@"http://127.0.0.1:8080/MJServer/login"]; 31 ASIFormDataRequest *request=[ASIFormDataRequest requestWithURL:url]; 32 33 //2.添加請求參數(請求體中得參數) 34 [request setPostValue:@"123" forKey:@"username"]; 35 [request setPostValue:@"123" forKey:@"pwd"]; 36 37 //3.發送請求 38 [request startAsynchronous]; 39 40 //4.監聽 41 [request setStartedBlock:^{ 42 //開始 43 NSLog(@"該方法會覆蓋代理方法中得對應方法"); 44 }]; 45 46 } 47 48 -(void)dealloc 49 { 50 #warning 當控制器銷毀的時候,清除並取消代理 51 [self.request clearDelegatesAndCancel]; 52 53 //如果是非arc的環境,那么還需要清空請求 54 //self.request=Nil; 55 } 56 #pragma mark-異步請求 57 /** 58 * 異步請求的第一種方式:設置代理,用代理方法監聽 59 */ 60 -(void)async1 61 { 62 //1.創建網絡請求(GET) 63 NSURL *url=[NSURL URLWithString:@"http://127.0.0.1:8080/MJServer/login?username=123&pwd=123"]; 64 self.request=[ASIHTTPRequest requestWithURL:url]; 65 //設置網絡請求的延時為10秒鍾 66 self.request.timeOutSeconds=10; 67 68 //2.設置代理 69 self.request.delegate=self; 70 71 72 //3.發送請求(異步請求) 73 [self.request startAsynchronous]; 74 } 75 76 #pragma mark-異步請求的代理方法 77 //請求開始的時候調用 78 -(void)requestStarted:(ASIHTTPRequest *)request 79 { 80 81 } 82 //接收到服務器返回的數據時調用(數據量比較大的時候,這個方法會被調用多次,每次只能拿到部分數據) 83 -(void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data 84 { 85 86 } 87 //請求結束的時候調用(在該方法中拿到最終的數據) 88 -(void)requestFinished:(ASIHTTPRequest *)request 89 { 90 //request.responseData:服務器返回的所有數據,這個data已經拼接了接收到的所有數據 91 } 92 //發送網絡請求失敗的時候調用 93 -(void)requestFailed:(ASIHTTPRequest *)request 94 { 95 } 96 97 /** 98 * 異步請求的第二種方式:selector,以設置代理為基本前提 99 */ 100 -(void)async2 101 { 102 //1.創建網絡請求(GET) 103 NSURL *url=[NSURL URLWithString:@"http://127.0.0.1:8080/MJServer/login?username=123&pwd=123"]; 104 self.request=[ASIHTTPRequest requestWithURL:url]; 105 //設置網絡請求的延時為10秒鍾 106 self.request.timeOutSeconds=10; 107 108 //2.設置代理 109 self.request.delegate=self; 110 111 //通過selector的方法,當請求開始的時候,由請求的代理即控制器調用start方法進行監聽 112 //說明:該方法會覆蓋代理方法 113 [self.request setDidStartSelector:@selector(start)]; 114 115 //3.發送請求(異步請求) 116 [self.request startAsynchronous]; 117 } 118 119 -(void)start 120 { 121 NSLog(@"該方法會覆蓋代理方法中得對應方法"); 122 } 123 124 /** 125 * 異步請求的第三種方式:使用block回調 126 */ 127 -(void)async3 128 { 129 //1.創建網絡請求(GET) 130 NSURL *url=[NSURL URLWithString:@"http://127.0.0.1:8080/MJServer/login?username=123&pwd=123"]; 131 self.request=[ASIHTTPRequest requestWithURL:url]; 132 //設置網絡請求的延時為10秒鍾 133 self.request.timeOutSeconds=10; 134 135 //2.使用block回調監聽 136 [self.request setStartedBlock:^{ 137 //請求開始的時候調用 138 }]; 139 [self.request setFailedBlock:^{ 140 //請求失敗的時候調用 141 }]; 142 [self.request setDataReceivedBlock:^(NSData *data) { 143 //開始接收數據的時候調用 144 }]; 145 [self.request setCompletionBlock:^{ 146 //請求成功完成的時候調用 147 }]; 148 149 //3.發送請求(異步請求) 150 [self.request startAsynchronous]; 151 } 152 153 154 #pragma mark-同步請求 155 -(void)sync 156 { 157 //1.創建網絡請求(GET) 158 NSURL *url=[NSURL URLWithString:@"http://127.0.0.1:8080/MJServer/login?username=123&pwd=123"]; 159 ASIHTTPRequest *request=[ASIHTTPRequest requestWithURL:url]; 160 //設置網絡請求的延時為10秒鍾 161 request.timeOutSeconds=10; 162 163 //2.發送請求(同步請求) 164 [request startSynchronous]; 165 166 167 //3.檢測服務器返回的結果 168 if (request.error) {//請求出錯,比如超時 169 NSLog(@"請求超時,錯誤信息為%@",request.error); 170 }else//請求成功 171 { 172 //打印狀態碼和狀態信息 173 NSLog(@"狀態碼---%d,狀態信息---%@",request.responseStatusCode, request.responseStatusMessage); 174 //打印返回的數據的長度 175 NSLog(@"返回數據的長度--%d",request.responseData.length); 176 //將返回的數據轉換為字符串 177 NSLog(@"返回的數據---%@",request.responseString); 178 179 //將服務器返回的數據解析為字典 180 NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:request.responseData options:NSJSONReadingMutableLeaves error:Nil]; 181 NSLog(@"%@",dictionary); 182 } 183 } 184 @end
程序說明:
(1)同步發送請求打印的消息
(2)異步發送請求
ASI以異步的方式發送網絡請求有三種方式,第一種是通過代理進行監聽;第二種方法是通過block進行監聽。還有一種方法時使用selector,這是建立在設置代理的基礎之上的,調用的方法會覆蓋代理方法。
第一種方法:
1 /** 2 * 異步請求的第一種方式:設置代理,用代理方法監聽 3 */ 4 -(void)async1 5 { 6 //1.創建網絡請求(GET) 7 NSURL *url=[NSURL URLWithString:@"http://127.0.0.1:8080/MJServer/login?username=123&pwd=123"]; 8 self.request=[ASIHTTPRequest requestWithURL:url]; 9 //設置網絡請求的延時為10秒鍾 10 self.request.timeOutSeconds=10; 11 12 //2.設置代理 13 self.request.delegate=self; 14 15 16 //3.發送請求(異步請求) 17 [self.request startAsynchronous]; 18 } 19 20 #pragma mark-異步請求的代理方法 21 //請求開始的時候調用 22 -(void)requestStarted:(ASIHTTPRequest *)request 23 { 24 25 } 26 //接收到服務器返回的數據時調用(數據量比較大的時候,這個方法會被調用多次,每次只能拿到部分數據) 27 -(void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data 28 { 29 30 } 31 //請求結束的時候調用(在該方法中拿到最終的數據) 32 -(void)requestFinished:(ASIHTTPRequest *)request 33 { 34 //request.responseData:服務器返回的所有數據,這個data已經拼接了接收到的所有數據 35 } 36 //發送網絡請求失敗的時候調用 37 -(void)requestFailed:(ASIHTTPRequest *)request 38 { 39 }
第二種方法:
1 /** 2 * 異步請求的第二種方式:selector,以設置代理為基本前提 3 */ 4 -(void)async2 5 { 6 //1.創建網絡請求(GET) 7 NSURL *url=[NSURL URLWithString:@"http://127.0.0.1:8080/MJServer/login?username=123&pwd=123"]; 8 self.request=[ASIHTTPRequest requestWithURL:url]; 9 //設置網絡請求的延時為10秒鍾 10 self.request.timeOutSeconds=10; 11 12 //2.設置代理 13 self.request.delegate=self; 14 15 //通過selector的方法,當請求開始的時候,由請求的代理即控制器調用start方法進行監聽 16 //說明:該方法會覆蓋代理方法 17 [self.request setDidStartSelector:@selector(start)]; 18 19 //3.發送請求(異步請求) 20 [self.request startAsynchronous]; 21 } 22 23 -(void)start 24 { 25 NSLog(@"該方法會覆蓋代理方法中得對應方法"); 26 }
第三種方法:
1 /** 2 * 異步請求的第三種方式:使用block回調 3 */ 4 -(void)async3 5 { 6 //1.創建網絡請求(GET) 7 NSURL *url=[NSURL URLWithString:@"http://127.0.0.1:8080/MJServer/login?username=123&pwd=123"]; 8 self.request=[ASIHTTPRequest requestWithURL:url]; 9 //設置網絡請求的延時為10秒鍾 10 self.request.timeOutSeconds=10; 11 12 //2.使用block回調監聽 13 [self.request setStartedBlock:^{ 14 //請求開始的時候調用 15 }]; 16 [self.request setFailedBlock:^{ 17 //請求失敗的時候調用 18 }]; 19 [self.request setDataReceivedBlock:^(NSData *data) { 20 //開始接收數據的時候調用 21 }]; 22 [self.request setCompletionBlock:^{ 23 //請求成功完成的時候調用 24 }]; 25 26 //3.發送請求(異步請求) 27 [self.request startAsynchronous]; 28 }
提示:block是ios4之后才引入的技術。
這兩種方法各有優缺點
說明:如果要同時發送多個請求,他們都設置控制器為自己的代理,這樣需要進行一些必要的判斷。而如果各自都是有block這樣的方式的話,那么將不會存在這些問題,多個請求之間相互不存在干擾。
新的問題:如果又有block又設置了代理,那么情況是什么樣子的呢?
答案是block和相關的代理方法都會被調用。
(3)補充
提示:ASI中已經考慮到了線程安全的問題。

3.發送POST請求。
代碼:

注意需要包含一個頭文件

內部默認就是POST的。

注意add和set的區別,一個是添加(適用於多值參數),一個是覆蓋(內部先remove,再add)。
服務器接收到的請求信息: