標籤:
NSURLSession,與NSURLConnection是並列的,且可以支援後台相關的網路操作的新特性;與NSURLConnection不同的是,NSURLSession把NSURLConnection替換成NSURLSession, NSURLSessionConfiguration,NSURLSessionTask。
NSURLSession一般分別兩部操作:第一,通過NSURLSession的執行個體建立task;第二,執行task;
而NSURLSessionTask,也就是task,可以把它當作所謂的任務。
NSURLSessionTask是一個抽象子類,它有三個具體的子類是可以直接使用的:NSURLSessionDataTask,NSURLSessionUploadTask和NSURLSessionDownloadTask。這三個類應用的三個基本網路任務:擷取資料、上傳檔案、下載檔案。與資料有關的NSURLSessionDataTask也可以勝任上傳下載的任務,所以經常使用到。
————樣本————–
一、GET方法
| 123456789101112131415 |
// 1.建立一個網路路徑NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://172.16.2.254/php/phonelogin?yourname=%@&yourpas=%@&btn=login",yourname,yourpass]];// 2.建立一個網路請求NSURLRequest *request =[NSURLRequest requestWithURL:url];// 3.獲得會話對象NSURLSession *session = [NSURLSession sharedSession];// 4.根據會話對象,建立一個Task任務:NSURLSessionDataTask *sessionDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSLog(@"從伺服器擷取到資料"); /* 對從伺服器擷取到的資料data進行相應的處理: */ NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableLeaves) error:nil]; }]; // 5.最後一步,執行任務(resume也是繼續執行): [sessionDataTask resume]; |
二、POST方法
| 12345678910111213141516171819 |
// 1.建立一個網路路徑NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://172.16.2.254/php/phonelogin"]];// 2.建立一個網路請求,分別佈建要求方法、請求參數NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL:url];request.HTTPMethod = @"POST";NSString *args = [NSString stringWithFormat:@"yourname=%@&yourpass=%@&btn=login",yourname,yourpass];request.HTTPBody = [args dataUsingEncoding:NSUTF8StringEncoding];// 3.獲得會話對象NSURLSession *session = [NSURLSession sharedSession];// 4.根據會話對象,建立一個Task任務NSURLSessionDataTask *sessionDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {NSLog(@"從伺服器擷取到資料");/*對從伺服器擷取到的資料data進行相應的處理.*/NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableLeaves) error:nil];}];//5.最後一步,執行任務,(resume也是繼續執行)。[sessionDataTask resume]; |
三、NSURLSessionDataDelegate代理方法
從前面兩種方法中,我們都可以看出,相比NSURLConnection,NSURLSession提供了block方式處理返回資料的簡便方式,但是,如果項目需要在網路請求資料的過程中,要做進一步的處理的話,需要調用NSURLSession的代理方法。
通常,使用代理方法需要先設定代理對象,但是通過查看NSURLSessionDataDelegate文檔,我們可以看到如下,代理屬性delegate為唯讀狀態。
| 1 |
@property (nullable, readonly, retain) id delegate; |
那麼我們需要怎樣設定代理對象呢?下面我們通過代碼示範關於代理方法的使用:
首先在檔案開頭添加代理協議,
| 123 |
#import@interface ViewController : UIViewController //遵循代理協議@end |
主方法的編寫如下:
| 123456789 |
// 1.delegateQueue參數表示協議方法將會在(NSOperationQueue)隊列裡面執行。(session的delegate屬性是唯讀,所以使用如下方法設定代理。)NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]delegate:selfdelegateQueue:[[NSOperationQueue alloc] init]];// 2.建立任務(因為要使用代理方法,就不需要block方式的初始化了)NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://172.16.2.254/php/phonelogin?yourname=%@&yourpass=%@&btn=login",yourname,yourpass]];NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:url]];// 3.執行任務[task resume]; |
關於代理行為:
| 123456789101112131415161718192021 |
#pragma mark -- NSURLSessionDataDelegate// 1.接收到伺服器的響應- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {//【注意:此處需要允許處理伺服器的響應,才會繼續載入伺服器的資料。 若在接收響應時需要對返回的參數進行處理(如擷取回應標頭資訊等),那麼這些處理應該放在這個允許操作的前面。】completionHandler(NSURLSessionResponseAllow);}// 2.接收到伺服器的資料(此方法在接收資料過程會多次調用)- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { // 處理每次接收的資料,例如每次拼接到自己建立的資料receiveData [self.receiveData appendData:data];}// 3.3.任務完成時調用(如果成功,error == nil)- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { if(error == nil){ /* 請求完成,成功或者失敗的處理 */ } else{ NSLog(@"請求失敗:%@",error); }} |
四、NSURLSessionDownloadTask
1.NSURLSessionDownloadTask:檔案下載任務
| 1234567891011121314151617 |
// 1.建立網路路徑NSURL *url = [NSURL URLWithString:@"http://172.16.2.254/php/phonelogin/image.png"] ;// 2.擷取會話NSURLSession *session = [NSURLSession sharedSession];// 3.根據會話,建立任務NSURLSessionDownloadTask *task = [session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) { /* a.location是沙箱中tmp檔案夾下的一個臨時url,檔案下載後會存到這個位置,由於tmp中的檔案隨時可能被刪除,所以我們需要自己需要把下載的檔案移動到其他地方:pathUrl. b.response.suggestedFilename是從相應中取出檔案在伺服器上儲存路徑的最後部分,例如根據本路徑為,最後部分應該為:“image.png” */ NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename]; NSURL *pathUrl = [NSURL fileURLWithPath:path]; // 剪下檔案 [[NSFileManager defaultManager] moveItemAtURL:location toURL:pathUrl error:nil]; }];// 4.啟動任務[task resume]; |
2.NSURLSessionDownloadDelegate代理方法:
首先添加協議
| 123 |
#import@interface ViewController : UIViewController //遵循代理協議@end |
代理方法如下:
| 123456789101112131415161718192021222324 |
// 1.每次寫入調用(會調用多次)- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { // 可在這裡通過已寫入的長度和總長度算出下載進度 CGFloat progress = 1.0 * totalBytesWritten / totalBytesExpectedToWrite; NSLog(@"%f",progress);}// 2.下載完成時調用- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTaskdidFinishDownloadingToURL:(NSURL *)location { // 這裡的location也是一個臨時路徑,需要自己移動到需要的路徑(caches下面) NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename]; [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:filePath] error:nil];}// 3.請求成功/失敗(如果成功,error為nil)- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { if(error == nil){ /* 請求完成,成功或者失敗的處理 */ } else{ NSLog(@"請求失敗:%@",error); }} |
五、NSURLSessionUploadTask
1. NSURLSessionUploadTask上傳檔案的方式有2種:
| 12 |
NSURLSessionUploadTask *task =[[NSURLSession sharedSession] uploadTaskWithRequest:request fromFile:fileNamecompletionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {}]; |
POST方法:
| 1234 |
[[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:bodycompletionHandler:^(NSData data, NSURLResponse response, NSError *error) { NSLog(@"-------%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);}]; |
不同的點,在於,用post方法需要添加網路路徑的請求體body,而在實際開發中,上傳檔案一般使用post方式,更加安全可靠。
其他:
當然,對於使用NSURLSession開發的項目來說,還有更多的方式可以執行,需要我們在日常開發過程多多發現,以便更好地使用這個較新的網路介面,例如AFNetWorking2.0版本之後,就有了基於NSURLSession的封裝運用,具體的有興趣的童鞋可以去github瞭解下。
iOS開發 GET、POST要求方法:NSURLSession篇