很多同學(xué)在遇到要使用網(wǎng)絡(luò)請求的時候跺撼,無腦Alamofire
敛摘,不是說這個庫不好用。畢竟第三方习贫,畢竟還要學(xué)習(xí)他得使用方法逛球,還要引入他得代碼。為何不嘗試下使用NSURLSession
苫昌,以前NSURLConnection
操作起來有很多不便颤绕,大家可能都愿意使用第三方庫。但是現(xiàn)在的NSURLSession
使用起來已經(jīng)很方便了祟身。我們何不利用學(xué)習(xí)Alamofire
的時間來學(xué)習(xí)學(xué)習(xí)NSURLSession
呢奥务?第三方庫也許有很多對json處理方便的加強(qiáng)功能,但是我們有時候只需要用他來做get , put ,post delete 請求 袜硫。還有一些下載上傳 氯葬、斷點下載等功能 其實NSURLSession
已經(jīng)夠用了。
最簡單的調(diào)用
if let url = NSURL(string: "https://httpbin.org/get") {
NSURLSession.sharedSession().dataTaskWithURL(url){ data, response, error in
//...
}.resume()
}
拿到一個 url 獲取默認(rèn)的session來處理url返回我們想要的數(shù)據(jù)
resume() 方法的調(diào)用婉陷,NSURLSession 默認(rèn)是不啟動的帚称,我們必須手工調(diào)用 resume() 方法,才會開始請求
NSURLSession 本身是不會進(jìn)行請求的秽澳,而是通過創(chuàng)建 task 的形式進(jìn)行網(wǎng)絡(luò)請求闯睹,同一個 NSURLSession 可以創(chuàng)建多個 task,并且這些 task 之間的 cache 和 cookie 是共享的担神。那么我們就來看看 NSURLSession 都能創(chuàng)建哪些 task 吧瞻坝。
NSURLSessionDataTask: 這個就是我們第一個例子中創(chuàng)建的 DataTask,它主要用于讀取服務(wù)端的簡單數(shù)據(jù),比如 JSON 數(shù)據(jù)杏瞻。其實這個請求不只是可以去數(shù)據(jù)所刀,修改,新增都是可以的捞挥,put , post
NSURLSessionDownloadTask: 這個 task 的主要用途是進(jìn)行文件下載浮创,它針對大文件的網(wǎng)絡(luò)請求做了更多的處理,比如下載進(jìn)度砌函,斷點續(xù)傳等等斩披。
NSURLSessionUploadTask: 和下載任務(wù)對應(yīng),這個 task 主要是用于對服務(wù)端發(fā)送文件類型的數(shù)據(jù)使用的讹俊。
那么NSURLSession只能通過NSURLSession.sharedSession()獲得嗎垦沉? -- NO,NSURLSession很強(qiáng)大 也是高度可配置的
NSURLSessionConfiguration
我們還可以通過NSURLSessionConfiguration
來創(chuàng)建一個NSURLSession 仍劈。有三種配置類型可供我們選擇
- defaultSessionConfiguration - 這個配置會使用全局的緩存厕倍,cookie 等信息,這個相當(dāng)于 NSURLSessionConfiguration 的默認(rèn)配置行為贩疙。
- ephemeralSessionConfiguration - 這個配置不會對緩存或 cookie 以及認(rèn)證信息進(jìn)行存儲讹弯,相當(dāng)于一個私有的 Session况既,如果你開發(fā)一個瀏覽器產(chǎn)品,這個配置就相當(dāng)于瀏覽器的隱私模式组民。
- backgroundSessionConfiguration - 這個配置可以讓你的網(wǎng)絡(luò)操作在你的應(yīng)用切換到后臺的時候還能繼續(xù)工作棒仍。
整個結(jié)構(gòu)大概就是這樣的
NSURLSessionConfiguration
還支持配置session的一些屬性,比如timeout 臭胜、cache添加http header等莫其,可以在這里 查閱所有可配置信息
那么我們來嘗試創(chuàng)建一個任務(wù)
//定義一個默認(rèn)的session
lazy var defaultSession = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
//獲取data的task
var dataTask:NSURLSessionDataTask?
/**
任務(wù)
*/
func doTask(){
guard let url = NSURL(string: "http://your.url") else { return }
dataTask = defaultSession.dataTaskWithURL(url)
dataTask?.resume()
}
這個例子 跟上面的簡單例子如出一轍,不過時我們自己創(chuàng)建的session耸三,把步驟分開了榜配。
看看如何去配置呢
func doTask2(){
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.timeoutIntervalForRequest = 10 //超時時間
configuration.requestCachePolicy = .UseProtocolCachePolicy //緩存策略
configuration.HTTPAdditionalHeaders = ["Content-Type":"application/json"] //header 配置
//更多配置詳見官方文檔...
let defaultSession2 = NSURLSession(configuration:configuration)
//獲取data的task
var dataTask:NSURLSessionDataTask?
guard let url = NSURL(string: "http://your.url") else { return }
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "get" //post put delete 等
//還有很多可以設(shè)置 更多設(shè)置 詳細(xì) command + 點擊 NSMutableURLRequest 就可以看到了
dataTask = defaultSession2.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
//操作數(shù)據(jù)
})
dataTask?.resume() //開啟任務(wù)
}
我們可以對configuration和request進(jìn)行配置 來達(dá)到我們想要的目的
對請求的操作室基于task的 這里的task也是可以cancel的
那么下載呢?
lazy var downloadsSession:NSURLSession = {
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
//delegateQueue設(shè)置為nil session會自己創(chuàng)建一個串行的隊列
return NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
}()
下載創(chuàng)建session和普通的請求差不多吕晌,我們這里添加了代理就可以拿到下載進(jìn)度
func doDownload(){
guard let url = NSURL(string: "http://your.download.url") else { return }
let downloadTask = downloadsSession.downloadTaskWithURL(url)
downloadTask.resume()
}
完成回調(diào)可以用閉包 也可以代理蛋褥。但是要拿到下載進(jìn)度 必須用代理了
class yourClass:NSURLSessionDownloadDelegate{
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
print("下載完成")
if let originalURL = downloadTask.originalRequest?.URL?.absoluteString,destinationURL = localFilePathForUrl(originalURL){
print("本地的臨時地址 : \(destinationURL)")
let fileManager = NSFileManager.defaultManager()
do {
try fileManager.removeItemAtURL(destinationURL)
} catch let error as NSError {
print("Error: \(error.localizedDescription)")
}
do {
try fileManager.copyItemAtURL(location, toURL: destinationURL)
} catch let error as NSError {
print("Error: \(error.localizedDescription)")
}
}
}
/**
監(jiān)控下載進(jìn)度
*/
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
if let downloadUrl = downloadTask.originalRequest?.URL?.absoluteString,download = activeDownloads[downloadUrl]{
download.progress = Float(totalBytesWritten)/Float(totalBytesExpectedToWrite)
let totalSize = NSByteCountFormatter.stringFromByteCount(totalBytesExpectedToWrite, countStyle: NSByteCountFormatterCountStyle.Binary)
if let trackIndex = trackIndexForDownloadTask(downloadTask),trackCell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: trackIndex, inSection: 0)) as? TrackCell{
}
}
}
當(dāng)然下載過程中也是可以取消的 直接調(diào)用task.cancel()
如果需要暫停
task.cancelByProducingResumeData { data in
if data != nil {
//將data保存本地 或者 內(nèi)存
}
}
繼續(xù)下載
//resumeData 為上次保存的data
task = downloadsSession.downloadTaskWithResumeData(resumeData)
task.resume()
上傳參照下載。睛驳。
本文參照 以及推薦擴(kuò)展閱讀http://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started
http://swiftcafe.io/2015/12/20/nsurlsession/
http://swiftcafe.io/2015/12/23/nsurlsession-app/
http://www.reibang.com/p/fb5aaeac06ef
建議大家去讀下raywenderlich的這片文章 講的很細(xì)