你好,歡迎來到IOS教程網

 Ios教程網 >> IOS使用技巧 >> IOS技巧綜合 >> iOS開發網絡篇—NSURLConnection基本使用

iOS開發網絡篇—NSURLConnection基本使用

編輯:IOS技巧綜合
[摘要]本文是對iOS開發網絡篇—NSURLConnection基本使用的講解,對學習IOS蘋果軟件開發有所幫助,與大家分享。

iOS開發網絡篇—NSURLConnection基本使用

一、NSURLConnection的常用類

(1)NSURL:請求地址

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

(3)NSMutableURLRequest:NSURLRequest的子類

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

二、NSURLConnection的使用 1.簡單說明

使用NSURLConnection發送請求的步驟很簡單

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

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

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

2.代碼示例

(1)發送請求的三個步驟:

1.設置請求路徑 2.創建請求對象 3.發送請求 3.1發送同步請求(一直在等待服務器返回數據,這行代碼會卡住,如果服務器,沒有返回數據,那麼在主線程UI會卡住不能繼續執行操作)有返回值 3.2發送異步請求:沒有返回值 說明:任何NSURLRequest默認都是get請求。 (2)發送同步請求代碼示例: 復制代碼
 1 //
 2 //  YYViewController.m
 3 //  01-NSURLConnection的使用(GET)
 4 //
 5 //  Created by apple on 14-6-28.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8 
 9 #import "YYViewController.h"
10 #import "MBProgressHUD+MJ.h"
11 
12 @interface YYViewController ()
13 @property (weak, nonatomic) IBOutlet UITextField *username;
14 @property (weak, nonatomic) IBOutlet UITextField *pwd;
15 - (IBAction)login;
16 
17 @end
18 
19 @implementation YYViewController
20 
21 - (IBAction)login {
22 //    1.提前的表單驗證
23     if (self.username.text.length==0) {
24         [MBProgressHUD showError:@"請輸入用戶名"];
25         return;
26     }
27     if (self.pwd.text.length==0) {
28         [MBProgressHUD showError:@"請輸入密碼"];
29         return;
30     }
31 //    2.發送請求給服務器(帶上賬號和密碼)
32     //添加一個遮罩,禁止用戶操作
33 //    [MBProgressHUD showMessage:@"正在努力加載中...."];
34 //    GET請求:請求行\請求頭\請求體
35 //
36 //    1.設置請求路徑
37     NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];
38     NSURL *url=[NSURL URLWithString:urlStr];
39 //    2.創建請求對象
40     NSURLRequest *request=[NSURLRequest requestWithURL:url];
41 //    3.發送請求
42     //發送同步請求,在主線程執行
43     NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
44     //(一直在等待服務器返回數據,這行代碼會卡住,如果服務器沒有返回數據,那麼在主線程UI會卡住不能繼續執行操作)
45     NSLog(@"--%d--",data.length);
46 }
47 @end
復制代碼

模擬器情況:

打印服務器返回的信息:

補充說明: 1.提前的表單驗證 2.發送請求給服務器(帶上賬號和密碼) GET請求:請求行\請求頭\請求體 注意:GET請求中不存在請求體,因為所有的信息都寫在URL裡面。在IOS裡面,請求行和請求頭都不用寫。 (3)發送異步請求 發送異步請求有兩種方式: 1)使用block回調 2)代理 A.使用block回調方法發送異步請求 使用block回調代碼示例: 復制代碼
 1 //
 2 //  YYViewController.m
 3 //  01-NSURLConnection的使用(GET)
 4 //
 5 //  Created by apple on 14-6-28.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8 
 9 #import "YYViewController.h"
10 #import "MBProgressHUD+MJ.h"
11 
12 @interface  ()
13 @property (weak, nonatomic) IBOutlet UITextField *username;
14 @property (weak, nonatomic) IBOutlet UITextField *pwd;
15 - (IBAction)login;
16 
17 @end
18 
19 @implementation YYViewController
20 
21 - (IBAction)login {
22 //    1.提前的表單驗證
23     if (self.username.text.length==0) {
24         [MBProgressHUD showError:@"請輸入用戶名"];
25         return;
26     }
27     if (self.pwd.text.length==0) {
28         [MBProgressHUD showError:@"請輸入密碼"];
29         return;
30     }
31 //    2.發送請求給服務器(帶上賬號和密碼)
32     //添加一個遮罩,禁止用戶操作
33     [MBProgressHUD showMessage:@"正在努力加載中...."];
34 
35 //
36 //    1.設置請求路徑
37     NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];
38     NSURL *url=[NSURL URLWithString:urlStr];
39     
40 //    2.創建請求對象
41     NSURLRequest *request=[NSURLRequest requestWithURL:url];
42     
43 //    3.發送請求
44     //3.1發送同步請求,在主線程執行
45 //    NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
46     //(一直在等待服務器返回數據,這行代碼會卡住,如果服務器沒有返回數據,那麼在主線程UI會卡住不能繼續執行操作)
47     
48     //3.1發送異步請求
49     //創建一個隊列(默認添加到該隊列中的任務異步執行)
50 //    NSOperationQueue *queue=[[NSOperationQueue alloc]init];
51     //獲取一個主隊列
52     NSOperationQueue *queue=[NSOperationQueue mainQueue];
53     [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
54         NSLog(@"--block回調數據--%@---%d", [NSThread currentThread],data.length);
55         //隱藏HUD,刷新UI的操作一定要放在主線程執行
56         [MBProgressHUD hideHUD];
57         
58         //解析data
59         /*
60         {"success":"登錄成功"}
61         {"error":"用戶名不存在"}
62         {"error":"密碼不正確"}
63          */
64         NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
65         NSLog(@"%@",dict);
66         
67         //判斷後,在界面提示登錄信息
68         NSString *error=dict[@"error"];
69         if (error) {
70             [MBProgressHUD showError:error];
71         }else
72         {
73             NSString *success=dict[@"success"];
74             [MBProgressHUD showSuccess:success];
75         }
76     }];
77     NSLog(@"請求發送完畢");
78 }
79 @end
復制代碼

模擬器情況(注意這裡使用了第三方框架):

打印查看:

代碼說明: block代碼段:當服務器有返回數據的時候調用會開一條新的線程去發送請求,主線程繼續往下走,當拿到服務器的返回數據的數據的時候再回調block,執行block代碼段。這種情況不會卡住主線程。 隊列的作用:決定這個block操作放在哪個線程執行? 刷新UI界面的操作應該放在主線程執行,不能放在子線程,在子線程處理UI相關操作會出現一些莫名的問題。 提示: (1)創建一個操作,放在NSOperation隊列中執行,默認是異步執行的。 (2)mainqueue 返回一個和主線程相關的隊列,即主隊列。 新的問題:如果向服務器發送請求,卻並沒有拿到數據,那麼程序會崩潰(data不能為空) 改進代碼: 復制代碼
 1  NSOperationQueue *queue=[NSOperationQueue mainQueue];
 2     [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
 3         //當請求結束的時候調用(有兩種結果,一個是成功拿到數據,也可能沒有拿到數據,請求失敗)
 4         NSLog(@"--block回調數據--%@---%d", [NSThread currentThread],data.length);
 5         //隱藏HUD,刷新UI的操作一定要放在主線程執行
 6         [MBProgressHUD hideHUD];
 7         
 8         //解析data
 9         /*
10         {"success":"登錄成功"}
11         {"error":"用戶名不存在"}
12         {"error":"密碼不正確"}
13          */
14         if (data) {//請求成功
15             NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
16             NSLog(@"%@",dict);
17             
18             //判斷後,在界面提示登錄信息
19             NSString *error=dict[@"error"];
20             if (error) {
21                 [MBProgressHUD showError:error];
22             }else
23             {
24                 NSString *success=dict[@"success"];
25                 [MBProgressHUD showSuccess:success];
26             }
27         }else   //請求失敗
28         {
29             [MBProgressHUD showError:@"網絡繁忙,請稍後重試!"];
30         }
31      
32     }];
復制代碼 解析data
   //解析data
        /*
        {"success":"登錄成功"}
        {"error":"用戶名不存在"}
        {"error":"密碼不正確"}
         */
說明:使用NSJSONSerialization 返回的對象,取決於最外層是什麼,如果是{}那就是字典,[]那就是數組等。 補充說明: 首先確定請求路徑,然後創建請求對象(默認發送的時get請求),使用異步方法(一調用這個方法,它會自動開啟一個子線程去發送請求,當請求成功,數據返回的時候自動調用內部的代碼段,這個代碼段在那個線程執行取決於隊列,如果是主隊列,那麼在子線程發送請求成功拿到服務器的數據後,回到主線程中解析數據,刷新UI界面)。 B.使用代理方法發送異步請求

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

常見大代理方法如下:

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

使用異步方法發送get請求的代碼示例:

復制代碼
  1 //
  2 //  YYViewController.m
  3 //  01-NSURLConnection的使用(GET)
  4 //
  5 //  Created by apple on 14-6-28.
  6 //  Copyright (c) 2014年 itcase. All rights reserved.
  7 //
  8 
  9 #import "YYViewController.h"
 10 #import "MBProgressHUD+MJ.h"
 11 
 12 @interface YYViewController ()<NSURLConnectionDataDelegate>
 13 @property (weak, nonatomic) IBOutlet UITextField *username;
 14 @property (weak, nonatomic) IBOutlet UITextField *pwd;
 15 @property(nonatomic,strong)NSMutableData *responseData;
 16 - (IBAction)login;
 17 
 18 @end
 19 
 20 @implementation YYViewController
 21 
 22 - (IBAction)login {
 23 //    1.提前的表單驗證
 24     if (self.username.text.length==0) {
 25         [MBProgressHUD showError:@"請輸入用戶名"];
 26         return;
 27     }
 28     if (self.pwd.text.length==0) {
 29         [MBProgressHUD showError:@"請輸入密碼"];
 30         return;
 31     }
 32 //    2.發送請求給服務器(帶上賬號和密碼)
 33     //添加一個遮罩,禁止用戶操作
 34     [MBProgressHUD showMessage:@"正在努力加載中...."];
 35 
 36 //
 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
復制代碼

打印查看:

補充:

(1)數據的處理

在didReceiveData:方法中,拼接接收到的所有數據,等所有數據都拿到後,在connectionDidFinishLoading:方法中進行處理

(2)網絡延遲

在做網絡開發的時候,一定要考慮到網絡延遲情況的處理,可以在服務器的代碼設置一個斷點模擬。

在服務器代碼的登錄方法中設置斷點

設置請求的最大延遲

模擬器情況:

打印查看:

三、NSMutableURLRequest

NSMutableURLRequest是NSURLRequest的子類,常用方法有

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

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

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

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

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved