網絡處理1-異步GET請求

前言

雲計算

近幾年來,雲計算是一個很是熱門的技術名詞,不少專家認爲,雲計算會改變互聯網的技術基礎,甚至會影響整個產業的格局。可能還不少人不瞭解什麼是雲計算,簡單來講,就是把用戶的數據(好比文檔、照片等)、用戶須要使用的軟件、用戶須要搜索的資源都保存在"雲端",並不用保存在用戶本地。你能夠將"雲端"看作了一臺超級計算機,實際上是由無數臺大型服務器組成的。html

移動應用

如今不少的移動應用也相似於"雲計算"的模式,好比新浪微博,用戶的數據都是保存在新浪服務器的數據庫裏面。當用戶想在手機上看到本身的微博數據時,大體須要如下幾個過程:ios

1.新浪微博手機客戶端發送HTTP請求到新浪服務器數據庫

2.服務器響應後返回數據給客戶端服務器

3.客戶端對數據進行解析後以圖形界面的形式(如列表形式)呈現給用戶網絡

網絡處理這一塊在移動開發中佔據着很是重要的地位,咱們這個專題主要來學習iOS網絡處理中的HTTP請求。app

 

1、API簡介

若是你想在iOS中發送Http請求的話,有不少方式能夠選擇,我在這裏介紹幾個常見的:框架

1.蘋果自帶的API

1> Core Foundation框架中的CFNetwork API:純C語言的API,性能很是高異步

2> Foundation框架中的NSURLConnection API:Objective-C的API,性能也不錯,簡單易用性能

2.第3方開源框架

1> ASIHttpRequest學習

2> AFNetworking

咱們這個專題主要來研究NSURLConnection的使用,至於第3方框架的學習,網上也有不少資源能夠搜索。

 

2、發送異步的GET請求

衆所周知,HTTP的主要請求方式有2種:GET請求和POST請求,接下來先演示下如何發送一個GET請求。

須要注意的是,你最好發送一個異步請求,不要發送同步請求。iOS程序啓動後,系統會默認建立一條主線程,也稱爲UI線程,這條主線程專門用來渲染UI界面、處理UI界面和用戶之間的交互,好比處理用戶的觸摸事件、文本輸入事件等。所謂異步請求,就是在後臺線程發送請求,不在主線程發送請求。通常狀況下,客戶端發出請求後,須要等待服務器的數據返回,若是服務器處理速度比較慢或者網速慢的話,可能要等很長時間。所以,若是你執意要發送同步請求,也就是在主線程發送請求,會形成主線程阻塞,容易出現卡機現象,給用戶帶來極差的體驗。

1.利用NSURLConnection發送異步請求

複製代碼
 1 // 請求地址
 2 NSString *urlString = @"http://192.168.1.102:8080/MJServer/login?username=123&pwd=123";
 3 
 4 // 初始化一個NSURL對象
 5 NSURL *url = [NSURL URLWithString:urlString];
 6 
 7 // 初始化一個請求
 8 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
 9 // 設置請求方法,能夠省略,默認就是GET請求
10 request.HTTPMethod = @"GET";
11 // 若是60秒事後服務器尚未相應,就算請求超時
12 request.timeoutInterval = 60;
13 
14 // 初始化一個鏈接
15 NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
16 // 開始一個異步請求
17 [conn start];
複製代碼

1> 第2行的是請求地址,因爲是GET請求,請求參數是直接拼接到路徑後面的

2> 第17行調用NSURLConnection的start方法發送一個HTPP請求,默認就是異步請求

 

2.NSURLConnectionDataDelegate

在前面的第15行代碼中,初始化NSURLConnection對象的時候傳了個self作代理(delegate),我這裏的self是控制器。在客戶端跟服務器交互過程會不斷地給這個代理對象發送消息,也就是會不斷地調用代理對象的相應方法。iOS在NSURLConnectionDataDelegate協議中定義了不少代理方法,我這裏只介紹經常使用的3個方法:

複製代碼
 1 #pragma mark - NSURLConnectionDataDelegate
 2 #pragma mark 接收到服務器返回的數據時調用(若是數據比較多,這個方法可能會被調用屢次)
 3 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
 4     NSLog(@"接收到服務器返回的數據");
 5     // 拼接數據
 6     [self.data appendData:data];
 7 }
 8 
 9 #pragma mark 網絡鏈接出錯時調用
10 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
11     NSLog(@"網絡鏈接出錯:%@", [error localizedDescription]);
12 }
13 
14 #pragma mark 服務器的數據已經接收完畢時調用
15 - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
16     NSLog(@"服務器的數據已經接收完畢");
17     // 解析成字符串數據
18     NSString *str = [[[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding] autorelease];
19     NSLog(@"%@", str);
20 }
複製代碼

1> 當服務器有數據返回時就會調用第3行的代理方法,返回的數據以NSData的格式傳入。若是數據比較多,好比下載大文件時,這個方法可能會被調用屢次。

2> 第6行用一個NSMutableData對象拼接服務器返回的全部數據,self.data是一個NSMutableData。

3> 當服務器已經成功返回全部的數據後,會調用第15行的代理方法,到此爲止,self.data裏面存放着服務器端返回的全部數據

4> 因爲我這邊服務器返回的是JSON字符串數據,因此在18行將self.data轉換爲NSString,而後打印出來看看數據對不對

 

3.對中文參數進行編碼

若是你的請求參數中含有中文,必須先進行編碼,而後再拼接到請求路徑後面。

下面的請求路徑寫法是錯誤的:

1 NSString *urlString = @"http://192.168.1.102:8080/MJServer/login?username=母雞";

應該這樣寫:

複製代碼
1 // 使用UTF-8對中文參數進行編碼
2 NSString *param = [@"母雞" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
3 
4 // 請求地址
5 NSString *baseUrl = @"http://192.168.1.102:8080/MJServer/login?username=";
6 NSString *urlString = [baseUrl stringByAppendingString:param];
複製代碼

1> 第2行使用UTF-8對中文參數進行編碼

2> 在第6行拼接編碼後的參數到請求路徑中

 

4.取消請求

若是用戶的網絡情況不是很好,那麼在登陸的過程當中,用戶極可能會點擊"取消"按鈕來取消登陸

當用戶點擊了取消按鈕,咱們也應該終止以前發送的請求,這時候能夠這樣作

[conn cancel];

conn是一個NSURLConnection對象

相關文章
相關標籤/搜索