對於iOS開發者來講,
AFNetworking
是咱們你們所熟知的,而Alamofire
呢?Alamofire
框架其實就是AFNetworking
兄弟,出自於同一個做者。既是同一個做者,那麼他們的使用方法,框架結構上應該也是保持一致的。AFNetworking、Alamofiregit
url
URLRequest
對象,配置請求相關信息URLSessionConfiguration
URLSession
通常經過以上幾個步來完成網絡請求,固然要根據不一樣應用場景來配置請求屬性。github
發起一個請求:json
func responseData() {
let url = "http://onapp.yahibo.top/public/?s=api/test/list"
Alamofire.request(url).responseJSON {
(response) in
switch response.result{
case .success(let json):
print("json:\(json)")
let dict = json as! Dictionary<String, Any>
let list = dict["data"] as! Array<AnyObject>
guard let result = [UserModel1].deserialize(from: list) else{return}
self.observable.onNext(result as [Any])
break
case .failure(let error):
print("error:\(error)")
break
}
}
}
複製代碼
responseJSON
爲相應類型,指定爲json
數據類型response
是Alamofire
對服務器響應結果的封裝headimg
HandyJSON
轉換爲模型數據,供UI
展現直接經過Alamofire
發起請求經過一個閉包返回請求結果,不須要二次封裝使用簡單。這裏咱們沒有標明請求類型,沒有請求參數,那Alamofire
是如何封裝這些請求參數的呢,點擊進入查看方法定義:swift
public func request( _ url: URLConvertible, method: HTTPMethod = .get, parameters: Parameters? = nil, encoding: ParameterEncoding = URLEncoding.default, headers: HTTPHeaders? = nil)
-> DataRequest
{
return SessionManager.default.request(
url,
method: method,
parameters: parameters,
encoding: encoding,
headers: headers
)
}
複製代碼
這裏已經提供了請求所須要的參數,並設置了默認值,所以外界在沒有指定方法時默認爲get
方式。根據實際開發需求設置響應的參數:api
Alamofire.request(url,method: .post,parameters: ["page":"1","size":"20"]).responseJSON
複製代碼
這是咱們開發中常見的設置請求方式,請求參數,這裏的url
支持多種數據類型,能夠是String、URL、URLRequest
等類型,爲何這麼設計呢?由於在項目中可能當前咱們跟前有一個String
類型的鏈接,也有多是個URL
類型的鏈接,這時候在不須要轉換的狀況下就能夠直接使用,方便快捷,更加靈活。數組
效果以下:緩存
一樣在Alamofire
中也是對URLSession
封裝的,在OC
中爲NSURLSession
,實際上是同樣的。通常網絡請求分三個步驟:安全
let url = URL.init(string: "協議://主機地址/路徑/參數1&參數2")!
複製代碼
http
協議仍是https
協議ip
地址或綁定ip
的域名get
參數拼接在鏈接上var request = URLRequest.init(url: url)
request.httpMethod = HTTPMethod.post.rawValue
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let postData = ["username":"hibo","password":"123456"]
request.httpBody = try?JSONSerialization.data(withJSONObject: postData, options: [])
request.timeoutInterval = 30
request.cachePolicy = .useProtocolCachePolicy
複製代碼
httpMethod
設置請求方式post
或get
setValue
設置請求頭信息httpBody
設置請求參數,參數打包在請求體中timeoutInterval
設置請求超時時間cachePolicy
設置網絡請求緩存策略經過以上的參數設置,可以感覺到發送一次請求是多麼不容易,所以網絡請求是必需要被封裝的服務器
URLSession.shared.dataTask(with: request) { (data, response, error) in
print("*******網絡請求*******")
do {
let list = try JSONSerialization.jsonObject(with: data!, options: .allowFragments)
print(list)
}catch{
print(error)
}
}.resume()
複製代碼
URLSession.shared
爲全局共享單例會話對象dataTask
建立網絡請求任務resume
默認爲掛起狀態,調用從新啓動網絡請求任務data
:請求到的數據流,經過JSONSerialization
序列化爲json
格式使用在URLSession.shared
中內部已經配置了該項,此項爲會話配置項,通常使用都會進行配置以適用於不一樣場景。查看該類以下:cookie
open class var `default`: URLSessionConfiguration { get }
open class var ephemeral: URLSessionConfiguration { get }
@available(iOS 8.0, *)
open class func background(withIdentifier identifier: String) -> URLSessionConfiguration 複製代碼
default
:默認模式,經常使用模式,在該模式下系統會建立持久化緩存,並在用戶的鑰匙串中保存證書ephemeral
:不支持持久性存儲,全部內容的會隨着session
的生命週期結束而釋放background
:與default
模式相似,在該模式下會建立一個獨立線程來傳輸網絡請求數據,能夠在後臺乃至APP關閉的時候也能夠進行數據傳輸建立一個會話:
let configuration = URLSessionConfiguration.background(withIdentifier: "request_id")
let session = URLSession.init(configuration: configuration, delegate: self, delegateQueue: OperationQueue.main)
session.dataTask(with: request) { (data, response, error) in
print("*******網絡請求*******")
do {
let list = try JSONSerialization.jsonObject(with: data!, options: .allowFragments)
print(list)
}catch{
print(error)
}
}.resume()
複製代碼
URLSessionDelegate
代理,實現代理方法,在本類中監控任務進度下載任務:
let configuration = URLSessionConfiguration.background(withIdentifier: "request_id")
let session = URLSession.init(configuration: configuration, delegate: self, delegateQueue: OperationQueue.main)
session.downloadTask(with: url).resume()
複製代碼
**注意在使用background
模式時必定要開啓後臺下載權限,不然沒法完成後臺下載並回調數據。**須要如下兩步才能完成:
一、開啓後臺下載權限
var backgroundHandler: (()->Void)? = nil
//設置此處開啓後臺下載權限
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
self.backgroundHandler = completionHandler
}
複製代碼
二、實現SessionDelegate
代理方法,調用閉包方法,通知系統更新屏幕
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
print("後臺任務下載回來")
DispatchQueue.main.async {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate, let backgroundHandle = appDelegate.backgroundHandler else { return }
backgroundHandle()
}
}
複製代碼
蘋果官方給出須要實現以上兩個方法來完成後臺下載,通知系統及時更新屏幕。官方文檔
一、常規屬性
identifier:
配置對象的後臺會話標識符httpAdditionalHeaders:
與請求一塊兒發送的附加頭文件字典networkServiceType:
網絡服務的類型allowsCellularAccess:
一個布爾值,用因而否應經過蜂窩網絡進行鏈接timeoutIntervalForRequest:
等待附加數據的超時時間timeoutIntervalForResource:
資源請求容許的最大時間範圍sharedContainerIdentifier:
應將後臺URL會話中的文件下載到的共享容器的標識符waitsForConnectivity:
一個布爾值,指示會話是否應等待鏈接變爲可用仍是當即失敗二、設置Cookie策略
httpCookieAcceptPolicy:
決定什麼時候接受cookie的策略常量httpShouldSetCookies:
一個布爾值,肯定請求是否包含來自cookie
存儲區的cookie
httpCookieStorage
:用於會話中存儲cookie
的cookie
存儲區HTTPCookie:
該對象爲不可變對象,從包含cookie
屬性的字典初始化,支持兩個不一樣的cookie版本,v0、v1
三、設置安全策略
TLS協議:
用於在兩個通訊應用程序之間提供保密性和數據完整性tlsMaximumSupportedProtocol:
在此會話中創建鏈接時客戶端應請求的最大TLS協議
版本tlsMinimumSupportedProtocol:
協議協商期間應接受的最小TLS協議
urlCredentialStorage:
爲身份驗證提供憑據的憑據存儲區四、設置緩存策略
urlCache:
用於爲會話中的請求提供緩存響應的URL
緩存requestCachePolicy:
決定什麼時候從緩存中返回響應的預約義常量五、支持後臺轉移
sessionSendsLaunchEvents:
一個布爾值,指示當傳輸完成時,應用程序應在後臺恢復仍是啓動isDiscretionary:
一個布爾值,用於肯定後臺任務是否能夠由系統自行安排已得到最佳性能shouldUseExtendedBackgroundIdleMode:
一個布爾值,指示當應用程序轉移到後臺時是否應保持TCP
鏈接打開六、支持自定義協議
protocolClasses:
在會話中處理請求的額外協議子類的數組URLProtocol:
該對象用來處理加載協議特定URL
數據七、支持多路徑TCP
multipathServiceType:
指定用於經過Wi-Fi
和蜂窩接口傳輸數據的多路徑TCP
鏈接策略的服務類型八、設置HTTP策略和代理屬性
httpMaximumConnectionsPerHost:
同時鏈接到給定主機的最大數量httpShouldUsePipelining:
一個布爾值,用於肯定會話是否使用HTTP
流水線connectionProxyDictionary:
包含相關要在此會話中使用的代理信息的字典九、支持鏈接更改
waitsForConnectivity:
一個布爾值,指示會話應等待鏈接可用仍是當即失敗一個請求任務就有如此多的配置屬性,可想而知對一個網絡框架的整合,工做量也是很是大的。接下來咱們就一步步來了解一下Alamofire是如何一步步整合的。