iOS-NSURLSession的使用

前言

iOS的網(wǎng)絡(luò)編程,主要圍繞NSURLConnection和NSURLSession來進(jìn)行。iOS7之后NSURLSession才出來,目前看起來NSURLConnection是有被拋棄的跡象,特別是2016年規(guī)定的所有網(wǎng)絡(luò)要支持ipv6,其中竟然沒有說到NSURLConnection。
了解一個系統(tǒng)類,需要補充非常多的背景知識,如果沒有這些背景知識,很難透徹理解整個類是如何運作的。不過作為api的調(diào)用者,往往可以不用管其內(nèi)部如何實現(xiàn)。Session可以被翻譯為會話,兩臺不同的計算機進(jìn)行通信的過程,其實就是會話的過程。

三步法請求

學(xué)習(xí)NSURLSession,免不了要和幾個重要的類打交道,比如NSURLSessionConfiguration/NSURLSession/NSURLSessionTask。使用起來,一般都有套路,下面先看看這些套路。

1、請求的URL
2、用URL生成Request,Http請求里面的請求頭內(nèi)容
3、生成Session,將Request作為參數(shù),調(diào)用Session的dataWithRequest來發(fā)送網(wǎng)絡(luò)請求

網(wǎng)絡(luò)請求三步法。對應(yīng)到代碼:

1、NSURL *url = [NSURL URLWithString:@"www.baidu.com/news/hfu3284"];
2、NSURLRequest *request = [NSURLRequest requestWithURL:url];
3、NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithRequest:request] resume];

套路只需要照著用就行了,可以暫時不管為何要按照這些套路來。
了解完基本的使用方式后,就可以根據(jù)使用場景來進(jìn)行說明了。一般app的網(wǎng)絡(luò)請求里面,http請求占了很大一部分,tcp當(dāng)然也有不過只在IM或者游戲這樣的功能里。下面看看http請求的幾個場景:

使用場景

網(wǎng)絡(luò)編程方面,如果脫離了具體的場景,理解起來特別困難,所有場景都是基于Http的,先了解這些使用場景。Http協(xié)議說白了就是兩臺計算機之間要通信,通信時的一些規(guī)則。所有的http請求,要么就是由客戶端向服務(wù)器請求文件,要么就是客戶端向服務(wù)器上傳文件。

使用場景一:http網(wǎng)絡(luò)請求

這個一般是業(yè)務(wù)接口,比如拉取json/xml數(shù)據(jù)。目前普遍用afnetworking來做。下面這個例子展示了非常簡單的http網(wǎng)絡(luò)請求,可以看到請求頭并未拼接參數(shù),稍微復(fù)雜一些的網(wǎng)絡(luò)參數(shù)則需要根據(jù)是GET還是POST來進(jìn)行相應(yīng)處理。


//1、請求字符串
NSString *str = @"http://swiftcafe.io/2015/12/20/nsurlsession/";
//2、轉(zhuǎn)化成url
NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
//3、構(gòu)建request
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//4、獲取session
NSURLSession *session = [NSURLSession sharedSession];
//5、用session發(fā)送請求,返回一個dataTask
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (data && (error == nil)) {
        NSLog(@"data=%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    }
    else {
        
        NSLog(@"error=%@",error);
    } }];
//6、dataTask創(chuàng)建后是掛起狀態(tài),需要調(diào)用resume開啟訪問
[dataTask resume];

使用場景二:文件下載

文件下載和一般的http請求不同的是task的不一樣,文件下載使用的是downloadTask,而且返回的block參數(shù)也不同,需要在block中對location進(jìn)行移動并保存,否則block執(zhí)行完就會刪除下載的文件。

// 1、請求字符串
NSString *str = [NSString stringWithFormat:@"http://swiftcafe.io/2015/12/20/nsurlsession/894.png"];
//2、轉(zhuǎn)化成url
NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
//3、構(gòu)建request
NSURLRequest *request = [NSURLRequest requestWithURL:url];

//4、獲取session
NSURLSession *session = [NSURLSession sharedSession];

//5、用session發(fā)送請求,返回一個downloadTask
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (error == nil) {
        //下載成功
        
    } else {
        //下載失敗
        
    }
}];

//6、downloadTask創(chuàng)建后是掛起狀態(tài),需要調(diào)用resume開啟訪問
[downloadTask resume];
  

使用場景三:文件上傳

文件上傳則需要用到POST方法,套路其實都很接近,只不過會有一個formData參數(shù)需要傳入,這個參數(shù)就是一些上傳文件的NSData。

// 1、請求字符串
NSString *str = [NSString stringWithFormat:@"http://swiftcafe.io/2015/12/20/nsurlsession/thumbnail.php"];
//2、轉(zhuǎn)化成url
NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
//3、構(gòu)建request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
//4、獲取session
NSURLSession *session = [NSURLSession sharedSession];

//5、用session發(fā)送請求,返回一個uploadTask
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[NSData dataWithContentsOfFile:@"IMG_0359.jpg"]     completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (error == nil) {
        NSLog(@"upload success:%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    } else {
        NSLog(@"upload error:%@",error);
    }
}];
//6、開始上傳
[uploadTask resume];

表單數(shù)據(jù)上傳

表單數(shù)據(jù)的上傳會比較麻煩,需要設(shè)置請求體的內(nèi)容。格式如下:

請求頭:
Content-Type:multipart/form-data;boundary=------------1345123513452323412352
請求體:
------------1345123513452323412352--
Content-Disposition:form-data; name="表單控件名"; filename="文件名"
Content-Type:MIME type
數(shù)據(jù)
--------------1345123513452323412352--


    NSData *imagedata = UIImageJPEGRepresentation(image, 0.7);
    
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost/dashboard/test.php"]];
     [request setHTTPMethod:@"POST"];
     [request setTimeoutInterval:20];
    
    NSMutableData *body = [NSMutableData data];
    
    //設(shè)置表單項分隔符
    NSString *boundary = @"---------------------------14737809831466499882746641449";
    
    //設(shè)置內(nèi)容類型
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"];
    
    //寫入圖片的內(nèi)容
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"PIC_DATA1.jpg\"\r\n",@"file"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:imagedata];
    [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    
    //寫入尾部內(nèi)容
    [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    
    [request setHTTPBody:body];

     NSURLSessionUploadTask * uploadtask = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:body completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSString * htmlString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
         NSLog(@"%@", htmlString);
    }];
    [uploadtask resume];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容