iOS-----使用NSURLConnection,nsurlconnection
使用NSURLConnection
如果只是為了讀取HTTP等伺服器資料,或向伺服器提交資料,iOS還提供了NSURLConnection類,NSURLConnection使用NSURLRequest向遠程伺服器發送同步或非同步請求,並擷取伺服器響應的資料。除了NSURLRequest之外,還可使用NSMutableURLRequest向伺服器發送資料。
使用NSURLConnection從網路擷取資料
NSURLConnection可用於根據URL載入伺服器響應,該對象的方法並不多,如果使用該對象來非同步載入伺服器響應,則需要為該對象指定一個遵守NSURLConnectionDelegate協議的對象,該對象作為NSURLConnection的delegate,負責處理非同步載入過程中的事件。
除此之外,還可使用NSURLConnection的sendSynchronousRequest:returningResponse:error:類方法同步架子啊伺服器響應。
NSURLConnection大致提供了如下常用的方法。
- (NSURLRequest *)originalRequest: 擷取該NSURLConnection最初的NSURLRequest對象的深拷貝 |
- (NSURLRequest *)currentRequest: 返回該NSURLConnection當前使用的NSURLRequest對象 |
採用同步請求的方式擷取網路資料的方法如下 |
+ sendSynchronousRequest:returningResponse:error:第1個參數代表發送請求的NSURLRequest對象;第2個參數需要傳入NSURLRequest對象的指標,用於擷取伺服器響應對象;第3個參數用於儲存擷取的錯誤資訊。 |
採用非同步請求的方式擷取網路資料的方法如下
+ connectionWithRequest:delegate::採用非同步請求的方式擷取資料。第2個參數作為NSURLConnection的delegate。 |
- initWithRequest:delegate: : 與上一個方法基本相同,只是該方法是執行個體方法,必須先調用alloc,再調用該方法 |
- initWithRequest:delegate:startImmediately:: 與前一個方法的功能基本相似,只是多了一個startImmediately參數,該參數控制是否立即發送請求 |
+ sendAsynchronousRequest:queue:completionHandler: : 該方法需要額外指定NSOperationQueue參數,表明將請求交給指定的NSOperationQueue處理. |
- start: 開始發送請求.只是當通過- initWithRequest:delegate:startImmediately:方法發送請求,且最後一個參數為NO時,才需要調用該方法。 |
使用NSURLConnection從網路擷取資料的步驟如下 |
1. 建立NSURLRequest對象,該對象代表對遠程伺服器的請求。該對象可以包括請求的URL、緩衝策略、逾時時間長度等資訊。 2. 調用NSURLConnection的執行個體方法或類方法,以NSURLRequest對象為參數建立NSURLConnection即可發送請求。 3. 如果調用方法以非同步方式載入伺服器響應,則需要為NSURLConnection對象指定delegate對象,因此還需要為delegete對象實現特定的方法。 |
程式碼片段 |
ViewController.m@implementation ViewControllerNSMUtableData* totalData;- (void)viewDidLoad{ [super viewDidLoad]; NSString* str = @http://www.crazyit.ory/ethos.php; totalData = [[NSMutableData alloc] init]; // 以指定NSString建立NSURL對象 NSURL * url = [NSURL URLWithString:str]; // 建立NSURLRequest對象 // NSURLRequest* request = [NSURLRequest requestWithURL:url];// 通過這種方式建立的NSURLRequest可以指定緩衝策略、逾時時間長度NSURLRequest* request = [NSURLRequest requestWithURL:urlcachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:5];// 以指定URL、delegate建立串連、發送請求NSURLConnection* conn = [NSURLConnection connectionWithRequest:request delegate:self ];// 如果conn為nil,則直接返回if(conn !=nil){ return;}}// 當伺服器響應產生時激發該方法- (void)connection: (NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ NSLog(@”++didReceiveResponse++”); NSLog(@”響應的資料類型:: %@” , response.MIMEType); // 擷取響應資料的長度,如果不能檢測到長度,則返回NSURLResponseUnknownLength(-1) NSLog(@”響應的資料長度為: %lld”, response.expectedContentLength); NSLog(@”響應的資料所使用的字元集: %@”, response.textEncodingName); NSLog(@”響應的檔案名稱: %@”, response.suggestedFilename);}// 每次讀取伺服器響應的資料時,都會激發該方法// 對於一個請求而言,伺服器資料可能要分幾次才能讀取,因此該方法將會被處罰多次// 如果程式需要將這些資料轉換成字串,則建議使用NSMutableData來收集這些資料.然後整體轉換- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*) data{ [totalData appendData:data];}// 當串連伺服器出現錯誤時激發該方法.可通過error擷取錯誤資訊- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ NSLog(@”++error++”);}// 當資料load完成時激發該方法.對於每次請求,該方法只會被激發一次- (void)connectionDidFinishLoading:(NSURLConnection *)connection{ NSLog(@”++finishLoading++”); NSString* content = [[NSString alloc] initWithData:totalDataencoding:NSUTF8StringEncoding];// 清空所有資料[totalData setLength:0];self.showView.text = content;}@end |
上面程式中的第1行紅色字代碼建立了一個NSURLRequest對象,第2行紅色字代碼以NSURLRequest對象為參數,以該視圖控制器本身作為delegate,建立了NSURLConnection對象,建立該對象即可向遠程伺服器發送請求。 由於程式制定使用視圖控制器本身作為NSURLConnection的delegate,因此該視圖控制器實現了NSURLConnectionDataDelegate協議,並實現了該協議中幾個特定的方法。 隨著伺服器響應的到來,NSURLConnection的delegate對象的如下方法依次被調用
1. connection:didReceiveResponse: 當伺服器響應到來時,激發該方法 2. connection: didReceiveData: 每次讀取伺服器響應的資料時,都會激發該方法.對於一個請求而言, 伺服器資料可能要分幾次才能讀取, 因此該方法將會被觸發多次. 3. connectionDidFinishLoading: 伺服器響應讀取完成時激發該方法. |
|
|
|
使用NSMutableURLRequest向伺服器發送資料
NSMutableURLRequest不僅可以添加要求標頭,還可以添加請求參數,這樣即可向伺服器發送資料了.
NSMutableURLRequest新增了如下常用方法 |
- addValue:forHTTPHeaderField: 該方法用於為NSMutableURLRequest添加要求標頭 |
- setAllHTTPHeaderFields: 該方法通過一個NSDictionary一次性地為NSMutableURLRequest設定多個要求標頭 |
- setHTTPBody: 設定NSMutableURLRequest的請求體資料-----也就是佈建要求參數 |
- setHTTPBodyStream: 以NSInputStream為參數設定NSMutableURLRequest的請求體資料.該方法與setHTTPBody方法只能設定一個 |
- setHTTPMethod: 設定提交請求的方式,要麼是POST,要麼是GET, 預設是GET. |
- setHTTPShouldHandleCookies: 設定該HTTP請求是否處理Cookie. |
- setValue:forHTTPHeaderField: 為指定的要求標頭佈建要求值 |
程式碼範例 |
1 ViewController.m 2 3 @implementation ViewController 4 5 NSMutableData* totalData; 6 7 - (void)viewDidLoad 8 9 { 10 11 [super viewDidLoad]; 12 13 NSString* str = @”http://192.168.1.88.8888/abc/login.jsp”; 14 15 totalData = [[NSMutableData alloc] init]; 16 17 // 以指定NSString建立NSURL對象 18 19 NSURL* url = [NSURL URLWithString:str]; 20 21 // 建立NSURLRequest對象 22 23 // NSURLRequest* request = [NSURLRequest requestWithURL: url]; 24 25 // 通過這種方式建立的NSURLRequest可以指定緩衝策略、逾時時間長度 26 27 NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url 28 29 cachePolicy:NSURLRequestReloadIgnoringLocalCacheData 30 31 timeoutInterval:5]; 32 33 // --------------------下面代碼開始佈建要求參數-------------------- 34 35 // 準備請求參數 36 37 NSString* post = [NSString stringWithFormat:@”name=%@&pass=%@”, @”crazyit.org”, @”瘋狂軟體”]; 38 39 // 將請求參數轉換為NSData 40 41 NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding]; 42 43 NSString *postLength = [NSString stringWithFormat:@”%d”, [postData length]]; 44 45 // 佈建要求的方式,預設發送GET請求 46 47 [request setHTTPMethod:@”POST”]; 48 49 // 添加兩個要求標頭 50 51 [request setValue:postLength forHTTPHeaderField:@”Content-Length”]; 52 53 [request setValue:@”application/x-www-form-urlencoded” 54 55 forHTTPHeaderField:@”Content-Type”]; 56 57 // 將請求資料設定為HTTP請求體 58 59 [request setHTTPBody:postData]; 60 61 // 以指定URL、delegate建立串連、發送請求 62 63 NSURLConnection* conn = [NSURLConnection connectionWithRequest:request 64 65 delegate:self]; 66 67 // 如果conn為nil,則直接返回 68 69 if(conn != nil) 70 71 { 72 73 return; 74 75 } 76 77 } 78 79 // 當伺服器響應產生時激發該方法 80 81 - (void)connection: (NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 82 83 { 84 85 NSLog(@”++didReceiveResponse++”); 86 87 NSLog(@”響應的資料類型:: %@” , response.MIMEType); 88 89 // 擷取響應資料的長度,如果不能檢測到長度,則返回NSURLResponseUnknownLength(-1) 90 91 NSLog(@”響應的資料長度為: %lld”, response.expectedContentLength); 92 93 NSLog(@”響應的資料所使用的字元集: %@”, response.textEncodingName); 94 95 NSLog(@”響應的檔案名稱: %@”, response.suggestedFilename); 96 97 } 98 99 // 每次讀取伺服器響應的資料時,都會激發該方法100 101 // 對於一個請求而言,伺服器資料可能要分幾次才能讀取,因此該方法將會被處罰多次102 103 // 如果程式需要將這些資料轉換成字串,則建議使用NSMutableData來收集這些資料.然後整體轉換104 105 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*) data106 107 {108 109 [totalData appendData:data];110 111 }112 113 // 當串連伺服器出現錯誤時激發該方法.可通過error擷取錯誤資訊114 115 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error116 117 {118 119 NSLog(@”++error++”);120 121 }122 123 // 當資料load完成時激發該方法.對於每次請求,該方法只會被激發一次124 125 - (void)connectionDidFinishLoading:(NSURLConnection *)connection126 127 {128 129 NSLog(@”++finishLoading++”);130 131 NSString* content = [[NSString alloc] initWithData:totalData132 133 encoding:NSUTF8StringEncoding];134 135 // 清空所有資料136 137 [totalData setLength:0];138 139 self.showView.text = content;140 141 }142 143 @end |
上面程式的關鍵在於紅色字代碼部分,該紅色字代碼設定了發送POST請求,而且將一個形如”name = crazyit.org&pass=瘋狂軟體”的字串轉換成NSData後作為請求參數,並根據請求參數設定了兩個要求標頭的值-----這樣就得到了一個帶請求參數的NSMutableURLRequest |