因?yàn)閕OS的權(quán)限限制椒振, 如果使用HTTP協(xié)議要配置info.plist, 將Allow Arbitary Loads設(shè)為YES泣洞。
iOS封裝了URLSession類處理HTTP交互森书, 支持交互文本、上傳文件建钥、下載文件藤韵。
一、 文本交互
一般是用POST請(qǐng)求將包體數(shù)據(jù)傳給后臺(tái)熊经, 后臺(tái)返回json包體給手機(jī)端荠察, 手機(jī)端解析json后做邏輯。
<pre> let urlStr = "http://baike.baidu.com/api/openapi/BaikeLemmaCardApi?scope=103&format=json&appid=379020&bk_key=swift&bk_length=600"
let url = URL(string: urlStr)
var request = URLRequest(url: url!) //請(qǐng)求
request.httpMethod = "POST" //修改http方法
//request.httpBody = Data(bytes: <#T##Array<UInt8>#>) //設(shè)置POST包體
let session = URLSession.shared
let date = Date()
print("創(chuàng)建任務(wù)奈搜, 時(shí)間:\(date.timeIntervalSince1970)")
//初始化請(qǐng)求
let dataTask = session.dataTask(with: request,
completionHandler: { (data, resp, err) in
let comDate = Date()
print("http返回悉盆, 時(shí)間:\(comDate.timeIntervalSince1970)")
if err != nil {
print(err.debugDescription)
} else {
let responseStr = String(data: data!,
encoding: String.Encoding.utf8)
//print(responseStr!) //包體數(shù)據(jù)
//print("mimeType: (resp?.mimeType) ")
//URLResponse類里沒(méi)有http返回值, 需要先強(qiáng)制轉(zhuǎn)換馋吗!
if let response = resp as? HTTPURLResponse {
print("code\ (response.statusCode)")
for (tab, result) in response.allHeaderFields {
print("(tab.description) - (result)")
}
if response.statusCode == 200 {
//JSON解析焕盟, 做邏輯
} else {
//通知UI接口執(zhí)行失敗
}
}
}
} ) as URLSessionTask
let beginDate = Date()
print("開始任務(wù), 時(shí)間:\(beginDate.timeIntervalSince1970)")
dataTask.resume() //執(zhí)行任務(wù)
let endDate = Date()
print("結(jié)束任務(wù)宏粤, 時(shí)間:\(endDate.timeIntervalSince1970))</pre>
這段代碼說(shuō)明幾個(gè)問(wèn)題:
1脚翘、 request.httpMethod參數(shù)可以修改HTTP的方法, 默認(rèn)是GET绍哎。
2来农、dataTask.resume()是異步執(zhí)行的,即不阻塞UI崇堰。 這里還有閉包的一個(gè)概念叫逃逸閉包沃于,對(duì)應(yīng)關(guān)鍵字@escapting, 它的意思是將閉包做為回調(diào)異步執(zhí)行(作用類似于Android的Runnable)海诲,調(diào)用時(shí)立刻返回繁莹。
<pre> open func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Swift.Void) -> URLSessionDataTask</pre>執(zhí)行日志:
<pre>創(chuàng)建任務(wù), 時(shí)間:1484230880.29283
開始任務(wù)特幔, 時(shí)間:1484230880.30001
結(jié)束任務(wù)咨演, 時(shí)間:1484230880.30009
http返回, 時(shí)間:1484230881.42724 </pre>
3蚯斯、 http交互成功后要判斷返回值薄风, 作為初學(xué)者我翻遍了URLResponse的方法, 就是沒(méi)有status code拍嵌。遭赂。。 后來(lái)無(wú)意中發(fā)現(xiàn)了HTTPResponse類撰茎, 試著強(qiáng)轉(zhuǎn)并輸出它的成員變量嵌牺, 果然好用。
<pre>code 200
Server - Apache
Content-Type - application/json
Transfer-Encoding - Identity
Date - Thu, 12 Jan 2017 14:21:21 GMT
Proxy-Connection - Keep-alive
Tracecode - 12812437700874983946011222</pre>
4、http執(zhí)行成功后就是要解析包體并做業(yè)務(wù)邏輯了逆粹, responseStr就是我們最終需要的json字符串募疮, 我們需要反序列化并做邏輯。
<pre> if response.statusCode == 200 {
//JSON解析僻弹, 做邏輯
} else {
//通知UI接口執(zhí)行失敗
}</pre>
二阿浓、 下載文件, 使用URLSession的API, 代碼很簡(jiǎn)單蹋绽。 重點(diǎn)是存儲(chǔ)位置芭毙, iOS會(huì)自動(dòng)生成一個(gè)臨時(shí)文件。 我們要做的是拷貝這個(gè)文件到我們想要的目錄下卸耘。
<pre>let url = URL(string: "http://img.pconline.com.cn/images/upload/upc/tx/wallpaper/1307/23/c0/23656308_1374564438338_800x600.jpg")
let request = URLRequest(url: url!)
let downloadTask = session.downloadTask(with: request)
downloadTask.resume() //開始下載任務(wù)
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
print("下載結(jié)束退敦, 存儲(chǔ)在(location.path)")
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
print("total: \(totalBytesWritten), current: \(bytesWritten)") //下載進(jìn)度
}
</pre>
日志:
<pre> total: 46276, current: 46276
下載結(jié)束, 存儲(chǔ)在/Users/brycegao/Library/Developer/CoreSimulator/Devices/8BE9C62E-042E-4B50-8F5D-78F857533650/data/Containers/Data/Application/3A6EB44A-2F88-4E79-9CFC-87713B9FC2E0/tmp/CFNetworkDownload_tnAj6u.tmp
</pre>
三蚣抗、上傳文件侈百, 因?yàn)闆](méi)有測(cè)試服務(wù)器,無(wú)法調(diào)試翰铡。 代碼跟上傳文件類似钝域。
<pre>let uploadTask = session.uploadTask(with: request, from: data) {
(data:Data?, response:URLResponse?, error:Error?) -> Void in
//上傳完畢
if error != nil{
print(error)
}else{
let str = String(data: data!, encoding: String.Encoding.utf8)
print("上傳完畢:(str)") //str是包體
}
}</pre>
小結(jié): iOS對(duì)HTTP/HTTPS交互封裝個(gè)一套完整方便的API,主要涉及URLSession锭魔、URLSesionTask例证、URLCache及其派生類; 支持文件迷捧、上傳/下載文件织咧。