Alamofire
Version:4.5.1
Swift Version: 4.0.3
Podfiles
# Uncomment the next line to define a global platform for your proje
platform :ios, '8.0'
target 'UseageAlamofire' do
use_frameworks!
pod 'Alamofire'
end
目錄:
Alamofire從基礎到進階 基礎請求與響應(一)
Alamofire從基礎到進階 小技巧(二)
創(chuàng)建一個簡單的Request
let request = Alamofire.request("http://httpbin.org/ip")
print("request = \(request)")
輸出:request = GET http://httpbin.org/ip
上面的 GET 是請求類型,后面緊跟的就是你的請求的地址售躁,還有另外兩種創(chuàng)建一個Request的方式:
request(_ urlRequest: )
-
request(_ url:, method:, parameters:, encoding:, headers: )
我們使用一下看看效果:
let urlRequest = URLRequest(url: URL(string: "http://httpbin.org/ip")!)
let request2 = Alamofire.request(urlRequest)
print("request2 = \(request2)")
輸出:request2 = GET http://httpbin.org/ip
let url = "http://httpbin.org/ip"
let method: HTTPMethod = .get
let parameters: Parameters = ["name": "chao"]
let encoding: URLEncoding = .default
let headers: HTTPHeaders = ["Content-Type": "application/json"]
let request3 = Alamofire.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers)
print("request3 = \(request3)")
輸出:request3 = GET http://httpbin.org/ip?name=chao
使用一下Response響應
我們已經學會了用Alamofire創(chuàng)建一個Request浴韭,我們最終想要的是從服務器拿到數(shù)據(jù)阻肩,我們可以這樣寫:
let url2 = "http://httpbin.org/ip"
Alamofire.request(url2).response(completionHandler: { defaultResponse in
print("request = ", defaultResponse.request)
print("-----------------------------------")
print("response = ", defaultResponse.response)
print("-----------------------------------")
print("data = ", defaultResponse.data)
print("-----------------------------------")
print("error = ", defaultResponse.error)
print("-----------------------------------")
print("metrics = ", defaultResponse.metrics)
print("-----------------------------------")
print("timeline = ", defaultResponse.timeline)
})
輸出:
response = Optional(<NSHTTPURLResponse: 0x60000002ff00> { URL: http://httpbin.org/ip } { Status Code: 200, Headers {
"Access-Control-Allow-Credentials" = (
true
);
"Access-Control-Allow-Origin" = (
"*"
);
Connection = (
"keep-alive"
);
"Content-Length" = (
32
);
"Content-Type" = (
"application/json"
);
Date = (
"Fri, 30 Mar 2018 10:41:03 GMT"
);
Server = (
"meinheld/0.6.1"
);
Via = (
"1.1 vegur"
);
"X-Powered-By" = (
Flask
);
"X-Processed-Time" = (
0
);
} })
-----------------------------------
data = Optional(32 bytes)
-----------------------------------
error = nil
-----------------------------------
metrics = Optional((Task Interval) <_NSConcreteDateInterval: 0x600000030e40> (Start Date) 2018-03-30 10:41:03 +0000 + (Duration) 0.677700 seconds = (End Date) 2018-03-30 10:41:03 +0000
(Redirect Count) 0
(Transaction Metrics) (Request) <NSURLRequest: 0x600000012b60> { URL: http://httpbin.org/ip }
(Response) <NSHTTPURLResponse: 0x60000002f580> { URL: http://httpbin.org/ip } { Status Code: 200, Headers {
"Access-Control-Allow-Credentials" = (
true
);
"Access-Control-Allow-Origin" = (
"*"
);
Connection = (
"keep-alive"
);
"Content-Length" = (
32
);
"Content-Type" = (
"application/json"
);
Date = (
"Fri, 30 Mar 2018 10:32:49 GMT"
);
Server = (
"meinheld/0.6.1"
);
Via = (
"1.1 vegur"
);
"X-Powered-By" = (
Flask
);
"X-Processed-Time" = (
0
);
} }
(Fetch Start) 2018-03-30 10:41:03 +0000
(Domain Lookup Start) (null)
(Domain Lookup End) (null)
(Connect Start) (null)
(Secure Connection Start) (null)
(Secure Connection End) (null)
(Connect End) (null)
(Request Start) 2018-03-30 10:41:03 +0000
(Request End) 2018-03-30 10:41:03 +0000
(Response Start) 2018-03-30 10:41:03 +0000
(Response End) 2018-03-30 10:41:03 +0000
(Protocol Name) (null)
(Proxy Connection) NO
(Reused Connection) YES
(Fetch Type) Local Cache
(Request) <NSURLRequest: 0x600000012a10> { URL: http://httpbin.org/ip }
(Response) <NSHTTPURLResponse: 0x60000002fb60> { URL: http://httpbin.org/ip } { Status Code: 200, Headers {
"Access-Control-Allow-Credentials" = (
true
);
"Access-Control-Allow-Origin" = (
"*"
);
Connection = (
"keep-alive"
);
"Content-Length" = (
32
);
"Content-Type" = (
"application/json"
);
Date = (
"Fri, 30 Mar 2018 10:41:03 GMT"
);
Server = (
"meinheld/0.6.1"
);
Via = (
"1.1 vegur"
);
"X-Powered-By" = (
Flask
);
"X-Processed-Time" = (
0
);
} }
(Fetch Start) 2018-03-30 10:41:03 +0000
(Domain Lookup Start) 2018-03-30 10:41:03 +0000
(Domain Lookup End) 2018-03-30 10:41:03 +0000
(Connect Start) 2018-03-30 10:41:03 +0000
(Secure Connection Start) (null)
(Secure Connection End) (null)
(Connect End) 2018-03-30 10:41:03 +0000
(Request Start) 2018-03-30 10:41:03 +0000
(Request End) 2018-03-30 10:41:03 +0000
(Response Start) 2018-03-30 10:41:03 +0000
(Response End) 2018-03-30 10:41:03 +0000
(Protocol Name) http/1.1
(Proxy Connection) NO
(Reused Connection) NO
(Fetch Type) Network Load
)
-----------------------------------
timeline = Timeline: { "Latency": 0.677 secs, "Request Duration": 0.678 secs, "Serialization Duration": 0.000 secs, "Total Duration": 0.678 secs }
上面輸出了很多很多的東西昂拂,我們來具體看看都有什么?
DefaultDataResponse
這個響應結果是Alamofire提供的一個結構體碟绑,我們看一下源碼:
/// 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 error encountered while executing or validating the request.
public let error: Error?
/// The timeline of the complete lifecycle of the request.
public let timeline: Timeline
var _metrics: AnyObject?
DefaultDataResponse結構體定義了上面這幾個屬性:
reqeuest
就是你定義的請求
reponse
是響應結果
data
是服務器返回給我們的數(shù)據(jù)
error
是執(zhí)行請求和驗證結果時候的錯誤
timeline
是該請求從請求到收到結果的一條時間線
_metrics
是iOS10及以后提供的一個時間線的屬性单默,和timeline大同小異稻轨,所以你要使用的話必須是支持iOS10以后的版本才能使用
/// 這樣寫就沒有問題了
if #available(iOS 10, *) {
print("metrics = ", defaultResponse.metrics)
}
不過除了response
響應處理以外我們還有4種其他的響應處理方式:
- responseJSON
- reponseData
- responseString
- responsePropertyList
在我們的程序里,大多數(shù)用到的是第一和第二種雕凹。
responseString響應處理的是字符串
responsePropertyList響應處理的是plist(類似于responseJSON)都是轉換成Any類型殴俱。
responseJSON是將服務器返回數(shù)據(jù)序列化為json然后轉換成Any.
reponseData是將服務器返回數(shù)據(jù)序列化為Data然后轉換成Data.
Alamofire強烈建議我們使用這四種去做處理,不建議我們使用DefaultResponse枚抵,這個就不糾結了我們用下面四種已經足夠了线欲。
先看responseData:
Alamofire.request(url2).responseData(completionHandler: { response in
print(response.result.value)
})
輸出:Optional(32 bytes)
我們看到了reponse.result,這個result是啥汽摹?我們點進去看看
enum Result<Value> {
case success(Value)
case failure(Error)
public var value: Value? {
switch self {
case .success(let value):
return value
case .failure:
return nil
}
}
}
/// 源碼我沒有展示完 我們只看關于這篇文章的
Reust是一個泛型的枚舉李丰,當我們使用responseData的使用,Value就會被轉換為Data逼泣,當我們調用response.result.vlaue的時候就會看到輸出了"Optional(32 bytes)"這很明顯是Data類型,然后我們把它解析出來看看是什么:
let url2 = "http://httpbin.org/ip"
Alamofire.request(url2).responseData(completionHandler: { response in
guard let value = response.result.value else { return }
let result = try? JSONSerialization.jsonObject(with: value, options: [])
guard let res = result else { return }
let dictionary = res as! [String: Any]
print("dictionary = ", dictionary)
})
輸出:dictionary = ["origin": 101.81.57.239]
這就是responseData的簡單用法了.
下面我們來看responseJSON怎么使用:
Alamofire.request(url2).responseJSON { response in
print(response.result.value)
}
輸出: Optional({ origin = "101.81.57.239";})
很明顯它是一個JSON格式趴泌,這就是Alamofire序列化為JSON的好處。為什么我們使用Reulst拉庶,因為它是Alamofire序列化好服務器給我們使用的一個屬性嗜憔,所以我們不用再去做序列化的操作,直接使用就好了氏仗。下面我們轉化成字典類型:
Alamofire.request(url2).responseJSON { response in
guard let value = response.result.value else { return }
let dictionary = value as! [String: Any]
print("dictionary = ", dictionary)
}
輸出:dictionary = ["origin": 101.81.57.239]
和responseData是一樣的輸出結果吉捶,但是比responseData要少兩步, 所以如果你的程序后臺返回的是JSON格式的數(shù)據(jù),你直接使用responseJSON要比responseData要方便很多。
--以此來記錄 Usage Alamofire ^ _^ --