安裝
- CocoaPods和Carthage都很方便安裝
安裝完,如果出現加載不到Alamofire,可以查看Cannot load underlying module for 'Alamofire' #441,問題應該可以解決。 - 手動安裝
- 下載Alamofire
- 將
Alamofire.xcodeproj
拖進到項目中
- 在"Embedded Binaries中添加
- command + B 編譯后就可以使用
關于 https://httpbin.org/ 網站
https://httpbin.org/ 網站可用來做http的各種請求測試使用,不過遺憾的是沒有POST等提交類型請求的測試
基本使用
一個簡單的請求:
import Alamofire
Alamofire.request("https://httpbin.org/get")
http中有請求(Request) 和 響應(Response)兩個重要概念。大部分http框架,都會使用request
和response
作為方法名。
看看Alamofire的request
方法的詳細參數:
public func request(
_ url: URLConvertible,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
encoding: ParameterEncoding = URLEncoding.default,
headers: HTTPHeaders? = nil)
-> DataRequest
{
有url
,method
,parameters
,encoding
,headers
五個參數,與http是相互對應的。其中只有url
是必須的,其它都有默認值。
請求后的響應處理
向http發送請求后,就需對響應結果進行處理。** Alamofire采用鏈式調用的方式處理響應,這種鏈式調用的方式最初應該是起源jQuery**。
響應處理的一般形式如下,response
就是響應結果。
Alamofire.request("https://httpbin.org/get").responseJSON { response in
}
Alamofire 提供了五種不同的響應處理:
// Response Handler - Unserialized Response
func response(
queue: DispatchQueue?,
completionHandler: @escaping (DefaultDataResponse) -> Void)
-> Self
// Response Data Handler - Serialized into Data
func responseData(
queue: DispatchQueue?,
completionHandler: @escaping (DataResponse<Data>) -> Void)
-> Self
// Response String Handler - Serialized into String
func responseString(
queue: DispatchQueue?,
encoding: String.Encoding?,
completionHandler: @escaping (DataResponse<String>) -> Void)
-> Self
// Response JSON Handler - Serialized into Any
func responseJSON(
queue: DispatchQueue?,
completionHandler: @escaping (DataResponse<Any>) -> Void)
-> Self
// Response PropertyList (plist) Handler - Serialized into Any
func responsePropertyList(
queue: DispatchQueue?,
completionHandler: @escaping (DataResponse<Any>) -> Void))
-> Self
五種方法的參數不同,但最后一參數都是一個回調的閉包,都可以寫成尾隨閉包形式。除了response
方法的回調參數是DefaultDataResponse
,其它都是DataResponse
:
public struct DataResponse<Value> {
/// The URL request sent to the server.
public let request: URLRequest?
/// The server's response to the URL request.
public let response: HTTPURLResponse?
/// The data returned by the server.
public let data: Data?
/// The result of response serialization.
public let result: Result<Value>
/// The timeline of the complete lifecycle of the request.
public let timeline: Timeline
/// Returns the associated value of the result if it is a success, `nil` otherwise.
public var value: Value? { return result.value }
/// Returns the associated error value if the result if it is a failure, `nil` otherwise.
public var error: Error? { return result.error }
var _metrics: AnyObject?
DataResponse
與DefaultDataResponse
最大的不同就是多了兩個屬性result
和value
,value
值就是格式化的不同類型。
響應處理的一些例子
-
response
Alamofire.request("https://httpbin.org/get").response { response in print("Request: \(response.request)") print("Response: \(response.response)") print("Error: \(response.error)") if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) { print("Data: \(utf8Text)") } }
response
方法的響應結果response
是DefaultDataResponse
,沒有進行過格式化處理。 -
responseData
Alamofire.request("https://httpbin.org/get").responseData { response in debugPrint("All Response Info: \(response)") if let data = response.result.value, let utf8Text = String(data: data, encoding: .utf8) { print("Data: \(utf8Text)") } }
responseData
方法對響應結果進行了處理,response.result.value
就是我們屬性的Data
類型。 - 鏈式調用
Alamofire.request("https://httpbin.org/get") .responseString { response in print("Response String: \(response.result.value)") } .responseJSON { response in print("Response JSON: \(response.result.value)") }
響應驗證
http響應結果中的不同狀態碼(100..<600
)表示不同結果。
- 手動驗證
Alamofire.request("https://httpbin.org/get") .validate(statusCode: 200..<300) .validate(contentType: ["application/json"]) .responseData { response in switch response.result { case .success: print("Validation Successful") case .failure(let error): print(error) } }
- 自動驗證
狀態碼在200..<300
的為正確,其它為錯誤。Alamofire.request("https://httpbin.org/get").validate().responseJSON { response in switch response.result { case .success: print("Validation Successful") case .failure(let error): print(error) } }
HTTP不同請求方式
request
方法的method
參數表示不同的方法。
Alamofire.request("https://httpbin.org/get") // method defaults to `.get`
Alamofire.request("https://httpbin.org/post", method: .post)
Alamofire.request("https://httpbin.org/put", method: .put)
Alamofire.request("https://httpbin.org/delete", method: .delete)
請求參數編碼
GET
的參數按照固定格式寫到URL中,其他類型則按照不同格式寫到請求body中。
-
GET參數編碼
let parameters: Parameters = ["foo": "bar"] // All three of these calls are equivalent Alamofire.request("https://httpbin.org/get", parameters: parameters) // encoding defaults to `URLEncoding.default` Alamofire.request("https://httpbin.org/get", parameters: parameters, encoding: URLEncoding.default) Alamofire.request("https://httpbin.org/get", parameters: parameters, encoding: URLEncoding(destination: .methodDependent)) // https://httpbin.org/get?foo=bar
-
POST參數編碼
let parameters: Parameters = [ "foo": "bar", "baz": ["a", 1], "qux": [ "x": 1, "y": 2, "z": 3 ] ] // All three of these calls are equivalent Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters) Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: URLEncoding.default) Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: URLEncoding.httpBody) // HTTP body: foo=bar&baz[]=a&baz[]=1&qux[x]=1&qux[y]=2&qux[z]=3
-
JSON編碼
let parameters: Parameters = [ "foo": [1,2,3], "bar": [ "baz": "qux" ] ] // Both calls are equivalent Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: JSONEncoding.default) Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: JSONEncoding(options: [])) // HTTP body: {"foo": [1, 2, 3], "bar": {"baz": "qux"}}
添加請求HTTP頭部
let headers: HTTPHeaders = [
"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
"Accept": "application/json"
]
Alamofire.request("https://httpbin.org/headers", headers: headers).responseJSON { response in
debugPrint(response)
}
HTTP認證
let user = "user"
let password = "password"
Alamofire.request("https://httpbin.org/basic-auth/\(user)/\(password)")
.authenticate(user: user, password: password)
.responseJSON { response in
debugPrint(response)
}
下載文件
Alamofire.download("https://httpbin.org/image/png").responseData { response in
if let data = response.result.value {
let image = UIImage(data: data)
}
}
另外可以下文件保存在本地:
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileURL = documentsURL.appendingPathComponent("pig.png")
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
Alamofire.download("https://httpbin.org/image/png", to: destination).response { response in
print(response)
if response.error == nil, let imagePath = response.destinationURL?.path {
let image = UIImage(contentsOfFile: imagePath)
self.imageView.image = image
self.tableView.reloadData()
}
}
上傳
- 上傳
Data
let imageData = UIImagePNGRepresentation(image!)! Alamofire.upload(imageData, to: "https://httpbin.org/post").responseJSON { response in debugPrint(response) }
- 上傳文件
let fileURL = Bundle.main.url(forResource: "video", withExtension: "mov") Alamofire.upload(fileURL!, to: "https://httpbin.org/post").responseJSON { response in debugPrint(response) }
- 上傳Multipart Form Data(表單提交)
Alamofire.upload( multipartFormData: { multipartFormData in multipartFormData.append(unicornImageURL, withName: "unicorn") multipartFormData.append(rainbowImageURL, withName: "rainbow") }, to: "https://httpbin.org/post", encodingCompletion: { encodingResult in switch encodingResult { case .success(let upload, _, _): upload.responseJSON { response in debugPrint(response) } case .failure(let encodingError): print(encodingError) } } )
請求中花費的各種時間
Alamofire.request("https://httpbin.org/get").responseJSON { response in
print(response.timeline)
}
結果:
Timeline: { "Latency": 1.527 secs, "Request Duration": 1.528 secs, "Serialization Duration": 0.001 secs, "Total Duration": 1.529 secs }