一.爲什麼要使用NSURLSession來替換NSURLConnection
1.在iOS9.0之後,以前使用的NSURLConnection過期,蘋果推薦使用NSURLSession來替換NSURLConnection完成網路請求相關操作。
2.NSURLSession的優勢:
NSURLSession支持http2.0協議
處理下載任務的時候可以直接把數據下載到磁盤中
支持後臺下載和上傳
同一個session發送多次請求,只需要建立一次連接(複用了TCP)
提供了全局的session並且可以統一配置,使用更加方便
下載的時候是多線程異步處理,效率更高
3.NSURLSession的使用非常簡單,先根據會話對象創建一個請求Task,然後執行該Task即可
4.NSURLSessionTask及其子類
NSURLSessionTask本身是一個抽象類,在使用的時候,通常是根據具體的需求使用它的幾個子類
NSURLSessionDataTask可以用來發送常見的Get,Post請求,既可以用來上傳也可以用來下載
NSURLSessionDownloadTask可以用來發送下載請求,專門用來下載數據
NSURLSessionUploadTask可以用來發送上傳請求,專門用來上傳數據
使用步驟:
創建Task,執行Task
二、使用NSURLSession發送GET請求
-(void)get
{
NSURL *url = [NSURL URLWithString:@"http://120"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//單例對象
NSURLSession *session = [NSURLSession sharedSession];
//創建task
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *_Nullable data, NSURLResponse * _Nullable response, NSError *_Nullable error){
}];
//執行task
[dataTask resume];
}
-(void)get2{
NSURL *url = [NSURL URLWithString:@"http://120"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//單例對象
NSURLSession *session = [NSURLSession sharedSession];
//創建task 這樣傳會自動將請求路徑作爲參數創建一個請求對象(GET),一定是GET請求
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *_Nullable data, NSURLResponse * _Nullable response, NSError *_Nullable error){
}];
//執行task
[dataTask resume];
}
三、發送POST請求
-(void)post
{
NSURL *url = [NSURL URLWithString:@"http://120"];
NSMUtableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = [@"username=wly&password=520",dataUsingEncoding:NSUTF8StringEncoding];
//單例對象
NSURLSession *session = [NSURLSession sharedSession];
//創建task
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *_Nullable data, NSURLResponse * _Nullable response, NSError *_Nullable error){
//這裏的代碼是在子線程調用的,如果要更新UI的話需要做一個線程間通信
}];
//執行task
[dataTask resume];
}
NSURLSession相關代理
//獲得會話對象配置信息
NSURLSessionConfiguration *config = [NSURLSessionConfiguration
defaultSessionConfiguration];
//設置代理
/*
第一個參數:會話對象的配置信息defaultSessionConfiguration 表示默認配置
第二個參數:誰成爲代理,此處爲控制器本身即self
第三個參數:隊列,該隊列決定代理方法在哪個線程中調用,可以傳主隊列|非主隊列
[NSOperationQueue mainQueue] 主隊列: 代理方法在主線程中調用
[[NSOperationQueue alloc]init] 非主隊列: 代理方法在子線程中調用
*/
NSURLSession *session = [NSURLSession sessionWithConfiguration:config
delegate:self
delegateQueue:[NSOperationQueue mainQueue]];
代理方法
//1.接收到服務器響應的時候調用該方法
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
//如果需要知道這個HTTP的所有信息,就需要獲得NSURLResponse的子類
NSHTTPURLResponse *htttpResponse = (NSHTTPURLResponse *)response;
//打印信息
NSLog(@"響應頭信息:%@",htttpResponse.allHeaderFields);
//定義一個容器用於接受服務器返回的數據
self.mData = [NSMutableData data];
//注意:和NSURLConnection不同點在於接收到響應信息之後,需要使用completionHandler回調告訴系統應該如何處理服務器返回的數據
//默認是取消的(NSURLSessionResponseCancel),下載(NSURLSessionResponseBecomeDownload),繼續傳遞數據(NSURLSessionResponseAllow),只有設置這個值之後纔會繼續執行其它代理方法
completionHandler(NSURLSessionResponseAllow);
}
//2.接收到服務器返回數據的時候會調用該方法,如果數據較大那麼該方法可能會調用多次
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
//拼接服務器返回的數據
[_mData appendData:data];
}
//3.當請求完成(成功|失敗)的時候會調用該方法,如果請求失敗,則error有值
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
//解析服務器返回的數據
//說明:(此處返回的數據是JSON格式的,因此使用NSJSONSerialization進行反序列化處理)
NSLog(@"代理方法返回的響應信息:%@",[NSJSONSerialization JSONObjectWithData:_mData options:kNilOptions error:nil]);
}
NSURLSessionDownloadTask大文件下載
NSURL *url = [NSURL URLWithString:@"http://120"];
NSMUtableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//單例對象
NSURLSession *session = [NSURLSession sharedSession];
//創建task,該方法內部已經實現了邊接收數據邊寫入沙盒(tmp)的操作,寫入到臨時文件目錄
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL *_Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error){
//在子線程中處理該處代碼
fullpath = [[NSSearchPathForDirectioriesIndomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
//文件剪切
[[NSFilemanager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullpath] error:nil]
}];
//執行task
[downloadTask resume];