NSURLSession網絡請求

Qvmaacvt 8年前發布 | 5K 次閱讀 iOS開發 移動開發

1.在iOS9.0之后,以前使用的NSURLConnection過期,蘋果推薦使用NSURLSession來替換NSURLConnection完成網路請求相關操作。

NSURLSession的使用非常簡單,先根據會話對象創建一個請求Task,然后執行該Task即可。

NSURLSessionTask本身是一個抽象類,在使用的時候,通常是根據具體的需求使用它的幾個子類。關系如下:

1.png

2.使用NSURLSession發送GET請求的方法和NSURLConnection類似,整個過程如下:

1)確定請求路徑(一般由公司的后臺開發人員以接口文檔的方式提供),GET請求參數直接跟在URL后面

2)創建請求對象(默認包含了請求頭和請求方法【GET】),此步驟可以省略

3)創建會話對象(NSURLSession)

4)根據會話對象創建請求任務(NSURLSessionDataTask)

5)執行Task

6)當得到服務器返回的響應后,解析數據(XML|JSON|HTTP)

第一種Get方法

//1.確定請求路徑
    NSURL *url=[NSURL URLWithString:@"http://123.207.175.144/Test1.php?Login=1"];

    //2.創建請求對象
    //請求對象內部默認已經包含了請求頭和請求方法(GET)
    NSURLRequest *request=[NSURLRequest requestWithURL:url];

    //3.獲得會話對象
    NSURLSession *session=[NSURLSession sharedSession];

    //4.根據會話對象創建一個Task(發送請求)
         /*
          第一個參數:請求對象
          第二個參數:completionHandler回調(請求完成【成功|失敗】的回調)
                    data:響應體信息(期望的數據)
                    response:響應頭信息,主要是對服務器端的描述
                    error:錯誤信息,如果請求失敗,則error有值
          */
    NSURLSessionDataTask *dataTask=[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error){
                                        if(error==nil){
                                          //6.解析服務器返回的數據
                                          //說明:(此處返回的數據是JSON格式的,因此使用NSJSONSerialization進行反序列化處理)
                                            NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];

                                            NSLog(@"%@",dict);
                                        }
                                    }];
    //5.執行任務
    [dataTask resume];

第二種Get方法

//1.確定請求路徑
    NSURL *url=[NSURL URLWithString:@"http://123.207.175.144/Test1.php?Login=1"];

    //2.獲得會話對象
    NSURLSession *session=[NSURLSession sharedSession];

    //3.根據會話對象創建一個Task(發送請求)
         /*
                  第一個參數:請求路徑
                  第二個參數:completionHandler回調(請求完成【成功|失敗】的回調)
                            data:響應體信息(期望的數據)
                            response:響應頭信息,主要是對服務器端的描述
                            error:錯誤信息,如果請求失敗,則error有值
                  注意:
                     1)該方法內部會自動將請求路徑包裝成一個請求對象,該請求對象默認包含了請求頭信息和請求方法(GET)
                     2)如果要發送的是POST請求,則不能使用該方法
        */
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error){

        //5.解析數據
        NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
        NSLog(@"%@",dict);
    }];

     //4.執行任務
    [dataTask resume];

3.使用NSURLSession發送POST請求的方法和NSURLConnection類似,整個過程如下:

1)確定請求路徑(一般由公司的后臺開發人員以接口文檔的方式提供)

2)創建可變的請求對象(因為需要修改),此步驟不可以省略

3)修改請求方法為POST

4)設置請求體,把參數轉換為二進制數據并設置請求體

5)創建會話對象(NSURLSession)

6)根據會話對象創建請求任務(NSURLSessionDataTask)

7)執行Task

8)當得到服務器返回的響應后,解析數據(XML|JSON|HTTP)

Post方法

//1.創建會話對象
    NSURLSession *session=[NSURLSession sharedSession];

    //2.根據會話對象創建task
    NSURL *url=[NSURL URLWithString:@"http://123.207.175.144/Test1.php"];

    //3.創建可變的請求對象
    NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];

    //4.修改請求方法為POST
    request.HTTPMethod=@"POST";

    //5.設置請求體
    request.HTTPBody=[@"Login=1" dataUsingEncoding:NSUTF8StringEncoding];

    //6.根據會話對象創建一個Task(發送請求)
         /*
                  第一個參數:請求對象
                  第二個參數:completionHandler回調(請求完成【成功|失敗】的回調)
                             data:響應體信息(期望的數據)
                             response:響應頭信息,主要是對服務器端的描述
                             error:錯誤信息,如果請求失敗,則error有值
          */
     NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error){

        //8.解析數據
        NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
        NSLog(@"%@",dict);
    }];

     //7.執行任務
    [dataTask resume];

4.有的時候,我們可能需要監聽網絡請求的過程(如下載文件需監聽文件下載進度),那么就需要用到代理方法。

代理方法

#import "ViewController.h"

@interface ViewController ()<NSURLSessionDataDelegate>
@property (nonatomic, strong) NSMutableData *responseData;
@end

@implementation ViewController

-(NSMutableData *)responseData
 {
         if (_responseData == nil) {
                 _responseData = [NSMutableData data];
             }
         return _responseData;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
     //[self performSelector:@selector(getAndSynchronousMethod)];
    [self delegateTest];
}

-(void)delegateTest
{
         //1.確定請求路徑
         NSURL *url = [NSURL URLWithString:@"http://123.207.175.144/Test1.php?Login=1"];

         //2.創建請求對象
         //請求對象內部默認已經包含了請求頭和請求方法(GET)
         NSURLRequest *request = [NSURLRequest requestWithURL:url];

         //3.獲得會話對象,并設置代理
         /*
            35      第一個參數:會話對象的配置信息defaultSessionConfiguration 表示默認配置
            36      第二個參數:誰成為代理,此處為控制器本身即self
            37      第三個參數:隊列,該隊列決定代理方法在哪個線程中調用,可以傳主隊列|非主隊列
            38      [NSOperationQueue mainQueue]   主隊列:   代理方法在主線程中調用
            39      [[NSOperationQueue alloc]init] 非主隊列: 代理方法在子線程中調用
            40      */
         NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];

         //4.根據會話對象創建一個Task(發送請求)
         NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];

         //5.執行任務
         [dataTask resume];

}

//1.接收到服務器響應的時候調用該方法
 -(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
 {
         //在該方法中可以得到響應頭信息,即response
         NSLog(@"didReceiveResponse--%@",[NSThread currentThread]);

         //注意:需要使用completionHandler回調告訴系統應該如何處理服務器返回的數據
         //默認是取消的
         /*
                     NSURLSessionResponseCancel = 0,        默認的處理方式,取消
                     NSURLSessionResponseAllow = 1,         接收服務器返回的數據
                     NSURLSessionResponseBecomeDownload = 2,變成一個下載請求
                     NSURLSessionResponseBecomeStream        變成一個流
                  */

         completionHandler(NSURLSessionResponseAllow);
}

//2.接收到服務器返回數據的時候會調用該方法,如果數據較大那么該方法可能會調用多次
 -(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
 {
         NSLog(@"didReceiveData--%@",[NSThread currentThread]);

         //拼接服務器返回的數據
         [self.responseData appendData:data];
}

//3.當請求完成(成功|失敗)的時候會調用該方法,如果請求失敗,則error有值
 -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
 {
         NSLog(@"didCompleteWithError--%@",[NSThread currentThread]);

         if(error == nil)
             {
                     //解析數據
                     NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:nil];
                     NSLog(@"%@",dict);
                 }
}

@end

以上運行結果

2.png

5.如果返回的字符有漢字,可以為NSDictionary提供一個分類,重寫系統中的方法。

#import "NSDictionary+Log.h"

@implementation NSDictionary (Log)
-(NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
 {
         //初始化可變字符串
         NSMutableString *string = [NSMutableString string];
         //拼接開頭[
         [string appendString:@"["];

         //拼接字典中所有的鍵值對
         [self enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
                 [string appendFormat:@"%@:",key];
                 [string appendFormat:@"%@",obj];
             }];

         //拼接結尾]
         [string appendString:@"]"];

         return string;
}

@end

運行結果

3.png

 

來自:http://www.jianshu.com/p/11907f606aa8

 

 本文由用戶 Qvmaacvt 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!