文章分享至我的個人技術部落格: https://cainluo.github.io/14980521480137.html
NSURLSession
在2013年的時候, 蘋果推出了iOS 7
, 這個版本的iOS
被稱為革命性的iOS
, 而我們以前所用到的NSURLConnection
這個網路庫也被蘋果爸爸給重構, 並且重新命名為NSURLSession
.
現在在GitHub
裡用的最多的兩個庫AFNetworking, SDWebImage都是用了NSURLSession
.
這裡就不廢話了, 直接來知識點吧.
網路通訊
關於Session
的意思, 我這裡找到一段比較古方的解釋:
Session
翻譯為中文意思是會話,我們知道,在七層網路協議中有物理層->資料鏈路層->網路層->傳輸層->會話層->表示層->應用層
,那我們可以將NSURLSession
類理解為會話層,用於管理網路介面的建立、維護、刪除等等工作,我們要做的工作也只是會話層之後的層即可,底層的工作NSURLSession
已經幫我們封裝好了.
看到這我們就很激動, 因為底層的東西不需要我們去管理, 這就輕鬆多了.
NSURLSession的分支
我們都知道蘋果爸爸用NSURLSession
代替了NSURLConnection
, 那麼NSURLSession
裡面到底有什麼呢?
NSURLSession
父類:
- NSURLSession
- NSURLSessionConfiguration
NSURLSessionTask
子類:
- NSURLSessionDataTask
- NSURLSessionUploadTask
- NSURLSessionDownloadTask
- NSURLSessionStreamTask (iOS 9後才支援)
他們的主要關係:
NSURLSessionTask
子類的繼承關係:
NSURLSessionDataTask
: 主要使用在請求一些比較簡單的資料, 比如我們常用的JSON
資料.
NSURLSessionDownloadTask
: 這個主要使用在進行一些檔案的下載, 它可以針對一些大檔案的網路請求做更多的處理, 比如獲取下載進度, 檔案的斷點續傳等等牛逼事情.
NSURLSessionUploadTask
: 這個和上面那個task
對應, 主要是給伺服器傳送檔案資料所使用的.
NSURLSessionStreamTask
: 提供TCP/IP
的一個連結入口, 方便進行傳輸.
使用NSURLSession
不要以為看完了上面就可以直接拿來和伺服器互動了啦, 因為NSURLSession
本身是不會進行請求, 需要通過建立對應的task
, 然後配置完之後, 再去呼叫resume()
方法才能夠進行tongxin.
這裡有一個好訊息就是同意個NSURLSession
是可以建立多個task
, 並且這些task
的cache
和cookie
都是共享的.
使用NSURLSession
的步驟:
- 建立
NSURLSession
物件 - 使用
NSURLSession
建立對應的task
- 最後一步就是呼叫
resume()
方法, 開始請求.
建立NSURLSession
物件有三種方法, 這裡就不建立工程裡, 直接貼程式碼吧:
第一種:
// 獲取一個共享的單例會話物件
NSURLSession *urlSession = [NSURLSession sharedSession];
複製程式碼
第二種:
// 用NSURLSessionConfiguration獲取一個特定的NSURLSession
NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:<#(nonnull NSURLSessionConfiguration *)#>];
複製程式碼
第三種:
// 用NSURLSessionConfiguration獲取一個特定的NSURLSession, 並且設定好代理物件, 和代理的佇列
NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:<#(nonnull NSURLSessionConfiguration *)#>
delegate:<#(nullable id<NSURLSessionDelegate>)#>
delegateQueue:<#(nullable NSOperationQueue *)#>]
複製程式碼
配置NSURLSession
剛剛我們也提到, NSURLSession
是沒法直接進行請求的, 所以我們需要去配置一下, 這裡也有三種配置的方法.
第一種:
// NSURLSessionConfiguration的預設配置, 這種配置會把快取資料儲存到磁碟上
@property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;
NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
複製程式碼
第二種:
// NSURLSessionConfiguration的第二種配置, 這種配置不會把資料持久化, 也就是說不會儲存到磁碟上
@property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration;
NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];
複製程式碼
第三種:
// 這個配置可以允許程式在後臺進行上傳和下載的操作, 給定一個Identifier可以在系統關閉應用之後重啟, 根據給定的`Identifier`終止正在下載或者上傳操作, 但如果是使用者手動關閉了應用, 系統就會取消所有後臺傳輸的會話, 官方建議, 如果要時候後臺操作的話, 把discretionary屬性設定成為YES, 可以獲得更好地效能.
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier NS_AVAILABLE(10_10, 8_0);
NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"backgroundSessionConfiguration"]];
複製程式碼
使用NSURLSession建立Task
剛剛我們也說了, NSURLSession
是有三個子類的Task
, 所以這裡我們也要分開來說說.
NSURLSessionDataTask
:
// 通過指定的NSURL來建立一個NSURLSessionDataTask
NSURLSessionDataTask *dataTask = [urlSession dataTaskWithURL:[NSURL URLWithString:@""]];
// 通過指定的NSURL物件來建立, 並同時執行完對應的任務後通過completionHandler:返回NSURLSessionDataTask
NSURLSessionDataTask *dataTask = [urlSession dataTaskWithURL:[NSURL URLWithString:@""]
completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
// 通過指定的NSURLRequest物件來建立一個NSURLSessionDataTask
NSURLSessionDataTask *dataTask = [urlSession dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]];
// 通過指定的NSURLRequest物件來建立, 並同時執行完對應的任務後通過completionHandler:返回NSURLSessionDataTask
NSURLSessionDataTask *dataTask = [urlSession dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]
completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
複製程式碼
--
NSURLSessionUploadTask
:
// 通過指定的NSURLRequest物件來建立一個NSURLSessionUploadTask
NSURLSessionUploadTask *uploadTask = [urlSession uploadTaskWithStreamedRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]];
// 通過指定的NSURLRequest物件來建立一個NSURLSessionUploadTask, 並且指定上傳時所需的資料來源
NSURLSessionUploadTask *uploadTask = [urlSession uploadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]
fromData:[NSData data]];
// 通過指定的NSURLRequest物件來建立一個NSURLSessionUploadTask, 並且指定上傳時所需的檔案源
NSURLSessionUploadTask *uploadTask = [urlSession uploadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]
fromFile:[NSURL URLWithString:@""]];
// 通過指定的NSURLRequest物件來建立, 指定上傳時所需的檔案源, 並且同時執行完對應的任務後通過completionHandler:來返回NSURLSessionUploadTask
NSURLSessionUploadTask *uploadTask = [urlSession uploadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]
fromFile:[NSURL URLWithString:@""]
completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
// 通過指定的NSURLRequest物件來建立, 指定上傳時所需的資料來源, 並且同時執行完對應的任務後通過completionHandler:來返回NSURLSessionUploadTask
NSURLSessionUploadTask *uploadTask = [urlSession uploadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]
fromData:[NSData data]
completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
複製程式碼
--
NSURLSessionDownloadTask
:
// 通過指定的NSURL物件來建立一個NSURLSessionDownloadTask
NSURLSessionDownloadTask *downloadTask = [urlSession downloadTaskWithURL:[NSURL URLWithString:@""]];
// 通過指定的NSURL物件來建立一個NSURLSessionDownloadTask, 並同時執行完對應的任務後通過completionHandler:返回NSURLSessionDownloadTask
NSURLSessionDownloadTask *downloadTask = [urlSession downloadTaskWithURL:[NSURL URLWithString:@""]
completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
// 通過指定的NSURLRequest物件來建立一個NSURLSessionDownloadTask
NSURLSessionDownloadTask *downloadTask = [urlSession downloadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]];
// 通過指定的NSURLRequest物件來建立一個NSURLSessionDownloadTask, 並同時執行完對應的任務後通過completionHandler:返回NSURLSessionDownloadTask
NSURLSessionDownloadTask *downloadTask = [urlSession downloadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]
completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
// 通過指定的NSData物件來建立一個NSURLSessionDownloadTask, 這個NSData物件是之前下載失敗或者是停止下載了的資料, 這就是我們常說的斷點續傳
NSURLSessionDownloadTask *downloadTask = [urlSession downloadTaskWithResumeData:[NSData data]];
// 通過指定的NSData物件來建立一個NSURLSessionDownloadTask, , 並同時執行完對應的任務後通過completionHandler:返回NSURLSessionDownloadTask, 同時也是支援斷點續傳
NSURLSessionDownloadTask *downloadTask = [urlSession downloadTaskWithResumeData:[NSData data]
completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
複製程式碼
NSURLSessionStreamTask
:
// 通過一個指定的NSNetService物件來建立NSURLSessionStreamTask
NSURLSessionStreamTask *streamTask = [urlSession streamTaskWithNetService:[[NSNetService alloc] init]];
// 通過一個指定的IP地址, 埠號來建立一個NSURLSessionStreamTask
NSURLSessionStreamTask *streamTask = [urlSession streamTaskWithHostName:@"192.168.1.1"
port:8888];
複製程式碼
NSURLSessionDelegate
剛剛講完了三種Task
, 這裡補充一下, 就是說我們無論會用哪一種Task
, 我們都可以指定對應的代理, 這裡有一張NSURLSession
代理關係圖:
代理類 | 作用 |
---|---|
NSURLSessionDelegate | 作為其他代理的最基類, 定義了最基礎的網路請求代理方法 |
NSURLSessionTaskDelegate | 定義了網路請求任務的代理方法 |
NSURLSessionDownloadDelegate | 定義了下載任務的代理方法, 比如獲取下載進度 |
NSURLSessionDataDelegate | 定義了上傳任務或普通資料任務的代理方法 |
NSURLSessionStreamDelegate | 這個代理方法是繼承於NSURLSessionTaskDelegate , 提供一個TCP/IP的連結代理方法. |
詳細大家都會用代理方法, 這裡就不介紹了.
執行任務
剛剛說完了那麼多東西, 最後就差執行任務了:
[task resume];
複製程式碼
醬紫就完事啦, 如果還想了解更多的話, 可以去看看蘋果爸爸的官方文件.
工程地址
專案地址: https://github.com/CainRun/iOS-10-Characteristic/tree/master/10.Siri%20Intents%20UI