蘋果自帶API:Foundation——NSURLConnection

轉自:文頂頂  點擊打開鏈接   M了個J 點擊打開鏈接

一、NSURLConnection的常用類

(1)NSURL:請求地址

(2)NSURLRequest:封裝一個請求,保存發給服務器的全部數據,包括一個NSURL對象,請求方法、請求頭、請求體....

(3)NSMutableURLRequest:NSURLRequest的子類

(4)NSURLConnection:負責發送請求,建立客戶端和服務器的連接。發送NSURLRequest的數據給服務器,並收集來自服務器的響應數據

二、NSURLConnection的使用

(1)創建一個NSURL對象,設置請求路徑(設置請求路徑)

(2)傳入NSURL創建一個NSURLRequest對象,設置請求頭和請求體(創建請求對象)

(3)使用NSURLConnection發送NSURLRequest(發送請求)




說明: 1、任何NSURLRequest默認都是get請求。由於是GET請求,請求參數是直接拼接到路徑後面的。GET請求:請求行\請求頭\請求體。注意:GET請求中不存在請求體, 因爲所有的信息都寫在URL裏面。在IOS裏面,請求行和請求頭都不用寫。
   2、調用NSURLConnection的start方法發送一個HTPP請求,默認就是異步請求。

1.利用NSURLConnection發送同步請求

 //
 //    1.設置請求路徑
     NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];
     NSURL *url=[NSURL URLWithString:urlStr];
 //    2.創建請求對象
     NSURLRequest *request=[NSURLRequest requestWithURL:url];
 //    3.發送請求
     //發送同步請求,在主線程執行
     NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
     //(一直在等待服務器返回數據,這行代碼會卡住,如果服務器沒有返回數據,那麼在主線程UI會卡住不能繼續執行操作)
     NSLog(@"--%d--",data.length);

2.利用NSURLConnection發送異步請求

發送異步請求有兩種方式:
1)使用block回調
2)代理

A.使用block回調方法發送異步請求

//    1.設置請求路徑
     NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];
     NSURL *url=[NSURL URLWithString:urlStr];
     
 //    2.創建請求對象
     NSURLRequest *request=[NSURLRequest requestWithURL:url];
     
 //    3.發送請求
     //3.1發送同步請求,在主線程執行
 //    NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
     //(一直在等待服務器返回數據,這行代碼會卡住,如果服務器沒有返回數據,那麼在主線程UI會卡住不能繼續執行操作)
     
     //3.1發送異步請求
     //創建一個隊列(默認添加到該隊列中的任務異步執行)
 //    NSOperationQueue *queue=[[NSOperationQueue alloc]init];
     //獲取一個主隊列
     NSOperationQueue *queue=[NSOperationQueue mainQueue];
     [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
         NSLog(@"--block回調數據--%@---%d", [NSThread currentThread],data.length);
         //隱藏HUD,刷新UI的操作一定要放在主線程執行
         [MBProgressHUD hideHUD];
         
         //解析data
         /*
         {"success":"登錄成功"}
         {"error":"用戶名不存在"}
           {"error":"密碼不正確"}
          */
	if (data){
         NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
         NSLog(@"%@",dict);
	}
}

說明:使用NSJSONSerialization 返回的對象,取決於最外層是什麼,如果是{}那就是字典,[]那就是數組等。
補充說明:
首先確定請求路徑,然後創建請求對象(默認發送的時get請求),使用異步方法(一調用這個方法,它會自動開啓一個子線程去發送請求,當請求成功,數據返回的時候自動調用內部的代碼段,這個代碼段在那個線程執行取決於隊列,如果是主隊列,那麼在子線程發送請求成功拿到服務器的數據後,回到主線程中解析數據,刷新UI界面)。

block代碼段:當服務器有返回數據的時候調用會開一條新的線程去發送請求,主線程繼續往下走,當拿到服務器的返回數據的數據的時候再回調block,執行block代碼段。這種情況不會卡住主線程。
隊列的作用:決定這個block操作放在哪個線程執行?
刷新UI界面的操作應該放在主線程執行,不能放在子線程,在子線程處理UI相關操作會出現一些莫名的問題。
提示:
(1)創建一個操作,放在NSOperation隊列中執行,默認是異步執行的。
(2)mainqueue   返回一個和主線程相關的隊列,即主隊列。

B.使用代理方法發送異步請求

要監聽服務器返回的data,所以使用<NSURLConnectionDataDelegate>協議

 #pragma mark- NSURLConnectionDataDelegate代理方法
 
 //當接收到服務器的響應(連通了服務器)時會調用
 
 -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
 
 //當接收到服務器的數據時會調用(可能會被調用多次,每次只傳遞部分數據)
 
 -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
 
 //當服務器的數據加載完畢時就會調用
 
 -(void)connectionDidFinishLoading:(NSURLConnection *)connection
 
 //請求錯誤(失敗)的時候調用(請求超時\斷網\沒有網\,一般指客戶端錯誤)
 
 -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error


 //
 37 //   2.1設置請求路徑
 38     NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];
 39     NSURL *url=[NSURL URLWithString:urlStr];
 40     
 41 //   2.2創建請求對象
 42 //    NSURLRequest *request=[NSURLRequest requestWithURL:url];//默認就是GET請求
 43     //設置請求超時
 44     NSMutableURLRequest *request=[NSMutableURLRequest  requestWithURL:url];
 45     request.timeoutInterval=5.0;
 46     
 47 //   2.3.發送請求
 48  //使用代理髮送異步請求(通常應用於文件下載)
 49     NSURLConnection *conn=[NSURLConnection connectionWithRequest:request delegate:self];
 50     [conn start];
 51     NSLog(@"已經發出請求---");
 52 }
 53 
 54 #pragma mark- NSURLConnectionDataDelegate代理方法
 55 /*
 56  *當接收到服務器的響應(連通了服務器)時會調用
 57  */
 58 -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
 59 {
 60     NSLog(@"接收到服務器的響應");
 61     //初始化數據
 62     self.responseData=[NSMutableData data];
 63 }
 64 
 65 /*
 66 *當接收到服務器的數據時會調用(可能會被調用多次,每次只傳遞部分數據)
 67 */
 68 -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
 69 {
 70     NSLog(@"接收到服務器的數據");
 71     //拼接數據
 72     [self.responseData appendData:data];
 73         NSLog(@"%d---%@--",self.responseData.length,[NSThread currentThread]);
 74 }
 75 
 76 /*
 77  *當服務器的數據加載完畢時就會調用
 78  */
 79 -(void)connectionDidFinishLoading:(NSURLConnection *)connection
 80 {
 81     NSLog(@"服務器的數據加載完畢");
 82     //隱藏HUD
 83     [MBProgressHUD hideHUD];
 84     
 85     //處理服務器返回的所有數據
 86     NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves error:nil];
 87     
 88     //判斷後,在界面提示登錄信息
 89     NSString *error=dict[@"error"];
 90     if (error) {
 91         [MBProgressHUD showError:error];
 92     }else
 93     {
 94         NSString *success=dict[@"success"];
 95         [MBProgressHUD showSuccess:success];
 96     }
 97     NSLog(@"%d---%@--",self.responseData.length,[NSThread currentThread]);
 98 }
 99 /*
100  *請求錯誤(失敗)的時候調用(請求超時\斷網\沒有網\,一般指客戶端錯誤)
101  */
102 -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
103 {
104 //     NSLog(@"請求錯誤");
105     //隱藏HUD
106     [MBProgressHUD hideHUD];
107     [MBProgressHUD showError:@"網絡繁忙,請稍後重試!"];
108 }
109 @end


三、NSMutableURLRequest

NSMutableURLRequest是NSURLRequest的子類常用方法

設置請求超時等待時間(超過這個時間就算超時,請求失敗)- (void)setTimeoutInterval:(NSTimeInterval)seconds;

設置請求方法(比如GET和POST)- (void)setHTTPMethod:(NSString *)method;

設置請求體- (void)setHTTPBody:(NSData *)data;

設置請求頭- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;

四、對中文參數進行編碼

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

五、異步POST請求

假如請求路徑是http://192.168.1.102:8080/MJServer/login,請求參數有2個:

  • username :母雞
  • pwd :123

1.POST請求細節分析

要想在iOS中發送一個POST請求,首先要了解POST請求的一些細節:

1> 跟GET請求不一樣的是,POST請求的請求參數不是拼接在請求路徑後面,而是以請求體的形式發送到服務器端。

2> POST請求需要發送兩部分的數據到服務器端:

請求體內容:所有的請求參數

username=%E6%AF%8D%E9%B8%A1&pwd=123

中文參數需要進行編碼,參數"母雞"被編碼成"%E6%AF%8D%E9%B8%A1"

請求頭信息:請求體長度、請求數據的類型

Content-Length是指請求體長度,Content-Type是指請求數據類型

1 // 請求地址
 2 NSString *urlString = @"http://192.168.1.102:8080/MJServer/login";
 3 // 初始化一個NSURL對象
 4 NSURL *url = [NSURL URLWithString:urlString];
 5 
 6 // 初始化一個請求
 7 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
 8 // 設置請求方法
 9 request.HTTPMethod = @"POST";
10 // 60秒請求超時
11 request.timeoutInterval = 60;
12 
13 // 拼接請求參數
14 NSString *params = @"username=母雞&pwd=123";
15 // 對字符串進行編碼後轉成NSData對象
16 NSData *data = [params dataUsingEncoding:NSUTF8StringEncoding];
17 // 設置請求體
18 request.HTTPBody = data;
19 
20 // 設置請求頭信息-請求體長度
21 NSString *contentLength = [NSString stringWithFormat:@"%i", data.length];
22 [request setValue:contentLength forHTTPHeaderField:@"Content-Length"];
23 // 設置請求頭信息-請求數據類型
24 [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
25 
26 // 初始化一個連接
27 NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
28 // 開始一個異步請求
29 [conn start];

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章