简介:
Alamofire是使用Swift语言开发的网络库,它和AFNetworking是同一班子的开发团队。
Alamofire使用链式编程实现的。具有简洁的语法,良好的性能和优秀的可读性等特点。
Alamofire,本质上是基于NSURLSession进行封装的,其核心是URLSession和URLSessionTask子类。其早期版本使用Alamofire.request(),5.0之后使用AF.request()。
一、Alamofire 基本使用
我们通过一个例子来了解:
struct JsonArray: Decodable {
let channels: [Json]
}
struct Json: Decodable {
let abbr_en: String
let channel_id: String?
let name: String
let name_en: String
let seq_id: Int
}
AF.request(urlString)
.responseDecodable(of: JsonArray.self) { response in
print(response)
}
短短几行代码,我们就写好一个请求网络了。
如果我们修改代码:
AF.request(URL(string: urlString)!)
.responseDecodable(of: JsonArray.self) { response in
print(response)
}
传入URL类型的url方法也正常进行。为什么呢,我们进入源码查看一下:
open func request(_ convertible: URLConvertible,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
encoding: ParameterEncoding = URLEncoding.default,
headers: HTTPHeaders? = nil,
interceptor: RequestInterceptor? = nil,
requestModifier: RequestModifier? = nil) -> DataRequest {
let convertible = RequestConvertible(url: convertible,
method: method,
parameters: parameters,
encoding: encoding,
headers: headers,
requestModifier: requestModifier)
return request(convertible, interceptor: interceptor)
}
看到了convertible: URLConvertible ,遵循了URLConvertible协议。
在来看一个问题:
为什么可以用AF.request呢?
我们查看代码发现,AF直接就是
Session.default。所以Alamofire就是基于NSURLSession进行封装的。
Alamofire支持4种返回响应处理方式:Data、String、 JSON、自定义类型。下面分别举例说明
//Data示例
let url = "https://httpny.org/get"
AF.request(url).responseData { response in
switch response.result {
case let .success(data):
print("data:\(String(describing: data))")
case let .failure(error):
print(error)
}
}
//String示例
AF.request(url).responseString { response in
switch response.result {
case let .success(data):
print("data:\(String(describing: data))")
case let .failure(error):
print(error)
}
}
//JSON示例
AF.request(url).responseJSON { response in
switch response.result {
case let .success(data):
print("data:\(String(describing: data))")
case let .failure(error):
print(error)
}
}
//自定义格式示例
AF.request(url).responseDecodable(of: PersonResponse.self) { response in
switch response.result {
case let .success(data):
print("data:\(String(describing: data))")
case let .failure(error):
print(error)
}
}
一般情况下使用的都是自定义类型of: PersonResponse.self
1.POST 提交例子:
struct Login: Encodable {
let email:String
let password:String
}
let login = Login(email: "aaa", password: "bbb")
AF.request("https://httpny.org/post",
method: .post,
parameters: login,
encoder: JSONParameterEncoder.default)
.response { response in
debugPrint(response)
}
2. HTTP Headers 请求头设置
提供3种初始化方式
/// 1. 无参构造
public init() {}
/// 通过以下方式添加值
func add(name: String, value: String)
func add(_ header: HTTPHeader)
/// 2. 通过 HTTPHeader 数组构造
public init(_ headers: [HTTPHeader])
let headers: HTTPHeaders = [
HTTPHeader(name: "Authorization", value: "Basic VXNlcm5hbWU6UGFzc3dvcmQ="),
HTTPHeader(name: "Accept", value: "application/json")
]
AF.request("https://httpbin.org/headers", headers: headers).responseJSON { response in
debugPrint(response)
}
/// 3. 通过key/value 构造
public init(_ dictionary: [String: String])
let headers: HTTPHeaders = [
"Authorization": "Basic VXNlcm5hbWU6UGFzc3dvcmQ=",
"Accept": "application/json"
]
AF.request("https://httpny.org/headers", headers: headers).responseJSON { response in
debugPrint(response)
}
3. 下载文件
下载到指定目录:
let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)
AF.download("https://httpny.org/image/png", to: destination).response { response in
debugPrint(response)
if response.error == nil, let imagePath = response.fileURL?.path {
let image = UIImage(contentsOfFile: imagePath)
}
}
下载恢复:
var resumeData: Data!
let download = AF.download("https://httpny.org/image/png").responseData { response in
if let data = response.value {
let image = UIImage(data: data)
}
}
// download.cancel(producingResumeData: true)
// Makes resumeData available in response only.
download.cancel { data in
resumeData = data
}
AF.download(resumingWith: resumeData).responseData { response in
if let data = response.value {
let image = UIImage(data: data)
}
}
4. 上传文件
上传进度:
let fileURL = Bundle.main.url(forResource: "video", withExtension: "mov")
AF.upload(fileURL, to: "https://httpbin.org/post")
.uploadProgress { progress in
print("Upload Progress: (progress.fractionCompleted)")
}
.responseDecodable(of: HTTPBinResponse.self) { response in
debugPrint(response)
}