近幾年來,雲計算是一個很是熱門的技術名詞,不少專家認爲,雲計算會改變互聯網的技術基礎,甚至會影響整個產業的格局。可能還不少人不瞭解什麼是雲計算,簡單來講,就是把用戶的數據(好比文檔、照片等)、用戶須要使用的軟件、用戶須要搜索的資源都保存在"雲端",並不用保存在用戶本地。你能夠將"雲端"看作了一臺超級計算機,實際上是由無數臺大型服務器組成的。html
如今不少的移動應用也相似於"雲計算"的模式,好比新浪微博,用戶的數據都是保存在新浪服務器的數據庫裏面。當用戶想在手機上看到本身的微博數據時,大體須要如下幾個過程:ios
1.新浪微博手機客戶端發送HTTP請求到新浪服務器數據庫
2.服務器響應後返回數據給客戶端服務器
3.客戶端對數據進行解析後以圖形界面的形式(如列表形式)呈現給用戶網絡
網絡處理這一塊在移動開發中佔據着很是重要的地位,咱們這個專題主要來學習iOS網絡處理中的HTTP請求。app
若是你想在iOS中發送Http請求的話,有不少方式能夠選擇,我在這裏介紹幾個常見的:框架
1> Core Foundation框架中的CFNetwork API:純C語言的API,性能很是高異步
2> Foundation框架中的NSURLConnection API:Objective-C的API,性能也不錯,簡單易用性能
1> ASIHttpRequest學習
2> AFNetworking
咱們這個專題主要來研究NSURLConnection的使用,至於第3方框架的學習,網上也有不少資源能夠搜索。
衆所周知,HTTP的主要請求方式有2種:GET請求和POST請求,接下來先演示下如何發送一個GET請求。
須要注意的是,你最好發送一個異步請求,不要發送同步請求。iOS程序啓動後,系統會默認建立一條主線程,也稱爲UI線程,這條主線程專門用來渲染UI界面、處理UI界面和用戶之間的交互,好比處理用戶的觸摸事件、文本輸入事件等。所謂異步請求,就是在後臺線程發送請求,不在主線程發送請求。通常狀況下,客戶端發出請求後,須要等待服務器的數據返回,若是服務器處理速度比較慢或者網速慢的話,可能要等很長時間。所以,若是你執意要發送同步請求,也就是在主線程發送請求,會形成主線程阻塞,容易出現卡機現象,給用戶帶來極差的體驗。
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請求,默認就是異步請求
在前面的第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,而後打印出來看看數據對不對
若是你的請求參數中含有中文,必須先進行編碼,而後再拼接到請求路徑後面。
下面的請求路徑寫法是錯誤的:
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行拼接編碼後的參數到請求路徑中
若是用戶的網絡情況不是很好,那麼在登陸的過程當中,用戶極可能會點擊"取消"按鈕來取消登陸
當用戶點擊了取消按鈕,咱們也應該終止以前發送的請求,這時候能夠這樣作
[conn cancel];
conn是一個NSURLConnection對象