- NSURLConnection在 iOS9 被宣布棄用浴讯,逐漸被 NSURLSession 替代;
- NSURLSession 蔼啦、 NSURLSessionConfiguration 榆纽、NSURLSessionTask 常用三個類;
- AFNetWorking 從2.0版本開始捏肢,就是在 NSURLSession 的基礎(chǔ)上封裝的奈籽;
NSURLSession
使用:
1 - 通過NSURLSession的實例創(chuàng)建 task 任務(wù);
2 - resume 執(zhí)行 task 任務(wù)
NSURLSessionTask
可以理解為任務(wù): 數(shù)據(jù)請求任務(wù)鸵赫,下載任務(wù)衣屏,上傳任務(wù)等;
- NSURLSessionTask 的子類
NSURLSessionDataTask 數(shù)據(jù)請求
NSURLSessionUploadTask 上傳
NSURLSessionDownloadTask 下載
NSURLSessionDataTask 數(shù)據(jù)請求任務(wù)
dataTask 是執(zhí)行數(shù)據(jù)請求相關(guān)的任務(wù)辩棒,但也可以用來執(zhí)行上傳和下載相關(guān)的任務(wù)狼忱,是我們使用最多的task膨疏;
- block 形式
簡單的get請求:
如果返回值比較簡單,則用這種簡單的block方式钻弄。
NSURLSession *session = [NSURLSession sharedSession]; //單例創(chuàng)建session對象
NSURL *url = [NSURL URLWithString: "http://www.baidu.com/signin?username=13800138008&password=123456"];
// 初始化task
NSURLSessionTask *task = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError error) {
//數(shù)據(jù)處理
NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}];
[task resume]; // 啟動任務(wù) :所有類型的task都要調(diào)用resume方法才會開始進(jìn)行請求
簡單的post請求:
NSURLSession *session = [NSURLSession sharedSession];
NSURL *url = [NSURL URLWithString: @"http://www.baidu.com/signin"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST"; //post請求
request.HTTPBody = [@"username=13800138008&password=123456" dataUsingEncoding:
NSUTF8StringEncoding];
// 通過request初始化task
NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}];
[task resume];
get 和 post 的區(qū)別:
請求方式 | 初始化task | 參數(shù)方式 |
---|---|---|
get | url | 參數(shù)拼接在 urlString 后面 |
post | request | 將參數(shù)通過 utf8 編碼成肘,然后放在request 的body中 |
- NSURLSessionDataDelegate 代理形式
簡單的數(shù)據(jù)可以用 block 的方式進(jìn)行處理,如果返回的數(shù)據(jù)比較復(fù)雜斧蜕,或者相對數(shù)據(jù)進(jìn)一步處理双霍,則使用 NSURLSession 的 delegate。
delegate 分幾個階段 : 響應(yīng)批销,接收數(shù)據(jù)洒闸,請求完成;
以get為例:
//創(chuàng)建session: session的delegate屬性是只讀的均芽;delegateQueue 表示代理方法在哪個隊列中執(zhí)行丘逸;
[NSURLSessionConfiguration defaultSessionConfiguration] 表示默認(rèn)配置
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
// 創(chuàng)建任務(wù)
NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com/login?userName=13800138008&password=123456"]]];
[task resume]; // 啟動任務(wù)
delegate方法:
// 接收到服務(wù)器的響應(yīng)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
completionHandler(NSURLSessionResponseAllow); // 允許處理服務(wù)器的響應(yīng),才會繼續(xù)接收服務(wù)器返回的數(shù)據(jù)
}
// 接收服務(wù)器的數(shù)據(jù)(會調(diào)用多次)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
// 處理接收到的數(shù)據(jù)
}
// 請求完成
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error {
// 請求完成掀宋,處理成功的數(shù)據(jù)或者拿到錯誤的error值
}
NSURLSessionDownloadTask 下載任務(wù)
和 一樣深纲,有通過 url 和 request 兩種方式來初始化 session;
- 通過 url 來初始化劲妙,bloc形式:
SURLSession *session = [NSURLSession sharedSession];
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com/source/icon/my.png"] ;
NSURLSessionDownloadTask *task = [session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
// 返回的 location 是沙盒中tmp文件夾下的一個臨時url湃鹊,文件下載后會存到這個位置,由于tmp中的文件隨時可能被刪除镣奋,所以我們需要自己需要把下載的文件挪到需要的地方
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask,YES) lastObject] stringByAppendingPathComponent: response.suggestedFilename];
// 移動文件币呵; response.suggestedFilename 是 url 中的最后一部分,如:my.png
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:path]
error:nil];
}];
[task resume]; // 啟動任務(wù)
- NSURLSessionDownloadDelegate 代理的形式:
// 每次寫入調(diào)用(會調(diào)用多次)
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
// 可在這里通過已寫入的長度和總長度算出下載進(jìn)度
CGFloat progress = 1.0 * totalBytesWritten / totalBytesExpectedToWrite;
NSLog(@"%f",progress);
}
// 下載完成調(diào)用
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(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];
}
// 任務(wù)完成調(diào)用
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
}
- 斷點下載
這種斷點下載只支持應(yīng)用內(nèi)斷點余赢,如果程序在下載過程中途關(guān)閉,則不能恢復(fù)下載哈垢。
// 取消下載 :用這種方式取消下載妻柒,可以得到將來用來恢復(fù)的數(shù)據(jù),保存起來
[self.task cancelByProducingResumeData:^(NSData *resumeData) {
self.resumeData = resumeData; //保存數(shù)據(jù)
}];
// 下載失敗導(dǎo)致的下載中斷會進(jìn)入此協(xié)議方法耘分,也可以得到用來恢復(fù)的數(shù)據(jù)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
// 保存恢復(fù)數(shù)據(jù)
self.resumeData = error.userInfo[NSURLSessionDownloadTaskResumeData];
}
// 恢復(fù)下載時接過保存的恢復(fù)數(shù)據(jù)
self.task = [self.session downloadTaskWithResumeData:self.resumeData];
[self.task resume]; // 啟動任務(wù)
NSURLSessionUploadTask 上傳任務(wù)
上傳方式有兩種:
1 -
NSURLSessionUploadTask *task = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromFile:fileName completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
}];
2 - post 方法: body 參數(shù)需要填寫request的請求體(http協(xié)議規(guī)定格式的大長串)
出于安全考慮举塔,用這種方法比較多;
[self.session uploadTaskWithRequest:request fromData: body completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}];
每個task 自身有都擁有下面幾個方法
- (void)suspend; 暫停當(dāng)前任務(wù)
- (void)resume; 啟動任務(wù)陶贼,也可以喚醒suspend狀態(tài)的任務(wù)
- (void)cancel; 取消當(dāng)前的任務(wù)啤贩,也可以向處于suspend狀態(tài)的任務(wù)發(fā)送cancel消息,任務(wù)如果被取消便不能再恢復(fù)到之前的狀態(tài)。
NSURLSessionConfiguration 配置
- 默認(rèn)配置
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.timeoutIntervalForRequest = 10; // 超時時間
config.allowsCellularAccess = YES; // 是否允許使用蜂窩網(wǎng)絡(luò)(后臺傳輸不適用)
- task有三種配置
+ (NSURLSessionConfiguration *)defaultSessionConfiguration; 默認(rèn)模式拜秧,會將緩存存儲在磁盤上
+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration; 瞬時會話模式,不會創(chuàng)建持久性存儲的緩存
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier;后臺會話模式章郁,允許程序在后臺進(jìn)行上傳下載工作