https://github.com/Alamofire/Alamofire
在某些特殊情况下需要做无参无处理的请求,那么其使用就十分简单:
Alamofire.AF.request("https://ww.baidu.com")
当然有时候可能附加参数:
Alamofire.AF.request("https://ww.baidu.com", parameters: ["id":"2014"])
正常状态下是这样的:
(注意GET请求尽量不要拼接url,一方面是url太长太繁琐后期修改十分麻烦,另一方面是get的url参数不支持中文编码,springboot后端环境)
func getRequest(){
let url = "http://www.baidu.com"
Alamofire.AF.request(url).responseJSON { (response) in
switch response.result {
case .success(let json):
print(json)
// Success in request and do a async or sync(NOT UI) task here.
break
case .failure(let error):
print("error:\(error)")
break
}
}
}
说明:老版本的Alamofire写法似乎不兼容,新版本需要在Alamofire后面加上".AF
",即Alamofire.AF.request()
。闭包里面捕获返回的数据。成功请求和失败请求均各有一种情况,在各个情况里面判断即可。
func postRequest(){
let url = "http://test.shop.com/user?login"
Alamofire.AF.request(url, method: .post, parameters: ["name":"jack","password":"123456"]).responseJSON { (response) in
switch response.result {
case .success(let json):
print(json)
break
case .failure(let error):
print("error:\(error)")
break
}
}
}
说明:写法和闭包及返回类型与GET一样。不同的是POST请求多了键值对,request()
这个方法第三个参数可以看出,数组里面存放的就是。
Alamofire自带网络状态判断类,这个方法只能调用一次进行判断。
let networker = NetworkReachabilityManager(host: "https://ww.baidu.com")
networker?.startListening() { status in
print("------> NETWORK STATUS: \(status)")
if status == .reachable(.ethernetOrWiFi) {
print("------> WIFI")
} else if status == .reachable(.cellular) {
print("------> CELLULAR")
} else if status == .notReachable {
print("------> ANAVIABLE NETWORK")
} else {
print("------> UNKNOWN")
}
上传支持的类型包括File、Data、Stream、MultipartFormData。
Stream类型:
let fileURL = Bundle.main.url(forResource: "tylor", withExtension: "zip")
Alamofire.AF.upload(fileURL!, to: "http://test.com/upload")
.uploadProgress { progress in // UI Thread.
print("------> CURRENT PROG: \(progress.fractionCompleted)")
}
.responseJSON { response in
debugPrint(response)
}
这里定义了一个简单的工具类,可以直接调用该类进行访问。
结构体里面是两种常用的请求方式,是为get和post。请求结束后该方法会自动将结果回调出去。
import Foundation
import Alamofire
import UIKit
enum MethodType {
case get
case post
}
class AlamofireUtil{
class func requestData(_ type : MethodType, URLString : String, parameters : [String : Any]? = nil, finishedCallback : @escaping (_ result : Any) -> ()) {
let method = type == .get ? HTTPMethod.get : HTTPMethod.post
Alamofire.AF.request(URLString, method: method, parameters: parameters).responseJSON { (response) in
switch response.result {
case .success(let json):
finishedCallback(json)
break
case .failure(let error):
print("error:\(error)")
break
}
}
}
}
使用:
AlamofireUtil.requestData(.get, URLString: "\(URLManager.getURL(type: "login"))\(loginView.accountTextField.text!)/\(loginView.passwordTextField.text!)") { result in
let jsonData = JSON(result)
// JSON数据解析并更新UI
}
自己的小示例用上述写法没任何文通,然而有时需要对第三方库进行封装以减少这些库对项目的侵入性,使用Protocol与闭包是个很好的选择。
Protocol
import Foundation
import SwiftyJSON
protocol NetworkUtil {
static func postRequest(URLString: String, parameters : [String : Any]?, callback: @escaping (_ result: Any) -> ())
static func getRequest(URLString: String, parameters : [String : Any]?,callback: @escaping (_ result: Any) -> ())
}
AlamofireLayer
import Foundation
import Alamofire
enum MethodType {
case get
case post
}
class AlamofireLayer{
class func requestData(_ type : MethodType, URLString : String, parameters : [String : Any]? = nil, finishedCallback : @escaping (_ result : Any) -> ()) {
let method = type == .get ? HTTPMethod.get : HTTPMethod.post
Alamofire.AF.request(URLString, method: method, parameters: parameters).responseJSON { (response) in
switch response.result {
case .success(let json):
finishedCallback(json)
break
case .failure(let error):
print("error:\(error)")
break
}
}
}
}
Impl
import Foundation
import SwiftyJSON
class NetworkImpl: NetworkUtil{
static func getRequest(URLString: String, parameters: [String : Any]?, callback: @escaping (Any) -> ()) {
AlamofireLayer.requestData(MethodType.get, URLString: URLString, parameters: parameters) { result in
callback(result)
}
}
public static func postRequest(URLString: String, parameters: [String : Any]?, callback: @escaping (Any) -> ()) {
AlamofireLayer.requestData(MethodType.post, URLString: URLString, parameters: parameters) { result in
callback(result)
}
}
}
使用
NetworkImpl.getRequest(URLString: "http:example.com", parameters: ["id": requestTrackId!]) { (response) in
let jsonData = JSON(response)
print("------> RAW DATA:\(jsonData)")
}
这样以来,每次调用时就是用接口,底层网络请求框架改变时只需改变底层与实现层即可,做到了“避免牵一发而动全身”这种效果。
Alamofire的request是在子线程里面的,但请求结果是回到了主线程,也就是说,可以在数据解析后直接进行UI更新。