2. NSURLConnection

NSURLConnection

一. iOS中發送HTTP請求的方案

  1. 蘋果原生

    • NSURLConnection: 用法簡單, 比較古老但是最直接的方案
    • NSURLSession: 功能比NSURLConnection強大, 蘋果目前推薦使用的技術(2013年推出, iOS7開始的技術)
    • CFNetwork: NSURL類型框架的底層實現, 純C語言
  2. 第三方框架

    • ASIHttpRequest: 外號HTTP終結者, 功能及其強大, 但是已經停止更新
    • AFNetworking: 簡單易用, 提供了大部分常用的功能, 維護使用者多
    • MKNetworkKit: 簡單易用, 印度阿三的產物, 使用者維護者較少
  3. 建議

    • 隨著AFN框架的普遍性以及眾多開發者合力維護, 建議盡量使用AFN框架
    • 并且, 為了提高開發效率, 建議直接使用三方框架

二. NSURLConnection發送GET請求

  1. 常用類的介紹

    • iOS中與網絡相關的類, 都是以NSURL開頭的類
    • NSURLRequest: 請求類, 每一個Request對象就代表一個請求, 其中包含的信息大致有:
      • NSURL對象, 代表請求的URL地址
      • 請求方法, 請求頭, 請求體
      • 請求超時的信息(通過代理方法來監聽)
      • 是否允許蜂窩移動網絡發送請求等等....
    • NSMutableURLRequest: 他是NSURLRequest的子類, 可以在請求的同時包含更多的詳細屬性參數, 多用于POST請求
    • NSURLConnection: 負責處理網絡交互的類
      • 負責發送請求, 建立客戶端和服務器連接的類
      • 發送數據給服務器, 并收集來自服務器的響應數據
  2. NSURLConnection的使用步驟

    • 創建一個NSURL對象, 也就是設置請求路徑
    • 使用NSURL對象來創建一個NSURLRequest對象, 并且設置請求頭, 請求體
    • 使用NSURLConnection發送請求(發送請求的常見方式如下)
      • 同步請求: + (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
      • 異步請求(不會卡住主線程): 根據對服務器返回數據的處理方式不同, 可分為兩種
        • block回調: + (void)sendAsynchronousRequest:(NSURLRequest*) request queue:(NSOperationQueue*) queue completionHandler:(void (^)(NSURLResponse* response, NSData* data, NSError* connectionError)) handler
        • 代理監聽請求結果: 注意遵守協議
          • 首先, 要在發送請求的同時設置代理: + (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate
          • 之后, 如果使用的是代理方法, 那么就需要手動發出網絡請求- (void)start
          • 最后, 可以通過各種代理方法來處理返回的數據
  3. GET請求的代碼示例:

     // 同步請求
     - (void)sendSync {
         
         // 1. 請求路徑
         NSURL *url = [NSURL URLWithString:@"http://192.168.1.101:88/login?username=MyiOS&pwd=999&type=JSON"];
         
         // 2. 創建請求對象
         // requeset內部會自動提供默認的請求頭信息,默認是以GET方式發送的
         NSURLRequest *request = [NSURLRequest requestWithURL:url];
         
         // 3. 發送請求
         // 3.1 響應頭,他和響應體都是以data數據返回的
         NSURLResponse *response = nil;
         
         // 3.2 發送請求獲取數據
         NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
         
         NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
         
         // 4. 打印響應頭
         NSLog(@"%@", response);
         
         NSLog(@"%@", [NSThread currentThread]); // 在主線程解析數據
     }
     
     // 異步請求 - block回調
     - (void)sendAsync {
         
         // 1. 請求路徑
         NSURL *url = [NSURL URLWithString:@"http://192.168.1.101:88/login?username=MyiOS&pwd=999&type=JSON"];
         
         // 2. 創建請求對象
         NSURLRequest *request = [NSURLRequest requestWithURL:url];
         
         // 3. 發送異步請求
         /*
          (NSURLRequest *)request  請求對象
          (NSOperationQueue *)queue  隊列(決定代碼在哪個線程中執行)
          completionHandler:(void (^)(NSURLResponse *response, NSData *data, NSError *connectionError))handler 連接完成后回調
             NSURLResponse *response  響應頭信息
             NSData *data             返回的數據
             NSError *connectionError 如果請求失敗,保存失敗信息
          */
         [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
             
             // 3.1 如果連接錯誤為nil,證明連接成功
             if (connectionError == nil) {
                 // 4. 解析返回的數據
                 NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
                 NSLog(@"%@", response);
                 NSLog(@"%@", [NSThread currentThread]); // 在子線程中解析數據
             }
         }];
         NSLog(@"%@", [NSThread currentThread]);
     }
     
     // 異步請求2 - 代理監聽
     - (void)sendAsync2 {
         
         // 1. 創建請求路徑
         NSURL *url = [NSURL URLWithString:@"http://192.168.1.101:88/login?username=MyiOS&pwd=999&type=JSON"];
         
         // 2. 創建請求對象
         NSURLRequest *request = [NSURLRequest requestWithURL:url];
         
         // 3. 設置代理,發送請求
         NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
         
         // 4. 開始發送網絡請求
         [connection start];
     }
     
     #pragma mark - 代理方法,當發送了請求之后,會調用的方法
     // 1. 當接收到了響應的時候調用
     - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
         
         // 當接收到了響應,就創建data對象,準備接收數據
         self.data = [NSMutableData data];
         NSLog(@"%@", response);
     }
     
     // 2. 當接收到了數據的時候調用
     /*
      1> 該方法可能調用多次,當返回數據較大的時候,系統會一點一點接收數據
      2> 把每次接收的數據拼接起來,等接收完成,就是完整的數據了
      */
     - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
         
         // 查看當前數據的長度
         NSLog(@"%ld", data.length);
         
         // 拼接數據
         [self.data appendData:data];
     }
     
     // 3. 當請求失敗的時候調用該方法
     - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
         
         NSLog(@"請求失敗");
     }
     
     // 4. 當請求完成的時候調用,請求已經完成,接收數據完畢
     - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
         
         // 解析數據
         NSLog(@"%@", [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding]);
         
         NSLog(@"數據接收完畢");
         NSLog(@"%@", [NSThread currentThread]);
     }
    

三. NSURLConnection發送POST請求

  1. NSMutableURLRequest

    • 普通的NSURLRequest默認發送的是GET請求, GET只能發送一些簡單的請求, 用于獲取數據
    • 而NSMutableURLRequest, 可以包含更多的請求信息, 如:
      • 修改請求方法: 默認的請求方式為GET
      • 設置最大請求時間: 當超過最大時間還沒連接成功的話, 那么認為請求失敗
      • 設置請求頭信息: 比如設置客戶端的信息(當前設備為iOS9.0)
      • 設置請求體: 請求體是將NSData的二進制數據, 發送給服務器, 通過這點就可以發送文件
    • 補充GET和POST的請求格式
  2. POST請求的簡單實現代碼

     - (void)post {
         
         // 1. 確定請求路徑
         NSURL *url = [NSURL URLWithString:@"http://192.168.2.101:40/lgoin"];
         
         // 2. 創建可變請求對象
         NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
         
         // 3. 修改請求方法為POST(因為默認為GET)
         request.HTTPMethod = @"POST";
         
         // 4. 設置最大請求時間
         request.timeoutInterval = 15; // 如果請求時間超過15秒還沒得到響應,那么認為請求失敗
         
         // 5. 設置請求頭信息(Key為User-Agent)
         [request setValue:@"iOS 9.0" forHTTPHeaderField:@"User-Agent"];
         
         // 6. 設置請求體(將參數發送給服務器)
         request.HTTPBody = [@"username=520it&pwd=520it&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
         
         // 7. 發送請求(異步)
         [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
             
             // 接收數據并解析
             if (connectionError == nil) {
                 
                 NSLog(@"數據接收完畢,開始解析");
                 NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
             }
         }];
     }
    
  3. 補充:

    • 如果你的系統版本是適配iOS7.0以后的版本, 盡量使用NSURLSession
    • 同時, 在企業開發中, 盡量使用AFN等三方框架來處理你的網絡請求, 提高開發效率
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • iOS開發系列--網絡開發 概覽 大部分應用程序都或多或少會牽扯到網絡開發,例如說新浪微博、微信等,這些應用本身可...
    lichengjin閱讀 3,721評論 2 7
  • 常用類 NSURL:請求地址 NSURLRequest:一個NSURLRequest對象就代表一個請求,它包含的信...
    JonesCxy閱讀 1,009評論 0 1
  • 基本使用 通過NSURLConnection發送請求常用的類NSURL : 用于創建網絡請求地址NSURLRequ...
    Mario_ZJ閱讀 442評論 0 0
  • 網絡基礎 Http: 蘋果原生: NSURLConnection 03年推出的古老技術 NSURLSession...
    木子尚武閱讀 299評論 0 0
  • 平時在項目中一直是用網絡請求的第三方框架 AFNetwork和 ASIHTTPRequest比較多一些。最近還是想...
    明若晴空閱讀 2,145評論 0 1