網絡處理1-異步GET請求


前言

雲計算

近幾年來,雲計算是一個非常熱門的技術名詞,很多專家認為,雲計算會改變互聯網的技術基礎,甚至會影響整個產業的格局。可能還很多人不了解什么是雲計算,簡單來說,就是把用戶的數據(比如文檔、照片等)、用戶需要使用的軟件、用戶需要搜索的資源都保存在"雲端",並不用保存在用戶本地。你可以將"雲端"看做了一台超級計算機,其實是由無數台大型服務器組成的。

移動應用

現在很多的移動應用也類似於"雲計算"的模式,比如新浪微博,用戶的數據都是保存在新浪服務器的數據庫里面。當用戶想在手機上看到自己的微博數據時,大致需要以下幾個過程:

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

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

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

網絡處理這一塊在移動開發中占據着非常重要的地位,我們這個專題主要來學習iOS網絡處理中的HTTP請求。

 

一、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方框架的學習,網上也有很多資源可以搜索。

 

二、發送異步的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對象


免責聲明!

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



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