[英]iOS create generic Alamofire request using swift
最近我开始使用 swift 学习 iOS 应用程序开发,所以我是新手。 我想在 swift 中实现 rest api 调用,发现我们可以使用URLRequest
来实现这一点。 所以我编写了generic method
来调用rest api的所有类型(如get, put, post
),如下所示。
import Foundation
//import Alamofire
public typealias JSON = [String: Any]
public typealias HTTPHeaders = [String: String];
public enum RequestMethod: String {
case get = "GET"
case post = "POST"
case put = "PUT"
case delete = "DELETE"
}
public enum Result<Value> {
case success(Value)
case failure(Error)
}
public class apiClient{
private var base_url:String = "https://api.testserver.com/"
private func apiRequest(endPoint: String,
method: RequestMethod,
body: JSON? = nil,
token: String? = nil,
completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) {
let url = URL(string: (base_url.self + endPoint))!
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = method.rawValue
urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
if let token = token {
urlRequest.setValue("bearer " + token, forHTTPHeaderField: "Authorization")
}
if let body = body {
urlRequest.httpBody = try? JSONSerialization.data(withJSONObject: body)
}
let session = URLSession(configuration: .default)
let task = session.dataTask(with: urlRequest) { data, response, error in
//NSLog(error)
completionHandler(data, response, error)
}
task.resume()
}
public func sendRequest<T: Decodable>(for: T.Type = T.self,
endPoint: String,
method: RequestMethod,
body: JSON? = nil,
token: String? = nil,
completion: @escaping (Result<T>) -> Void) {
return apiRequest(endPoint: endPoint, method: method, body:body, token: token) { data, response, error in
guard let data = data else {
return completion(.failure(error ?? NSError(domain: "SomeDomain", code: -1, userInfo: nil)))
}
do {
let decoder = JSONDecoder()
try completion(.success(decoder.decode(T.self, from: data)))
} catch let decodingError {
completion(.failure(decodingError))
}
}
}
}
这就是我从controller
调用它的方法
public func getProfile(userId :Int, objToken:String) -> Void {
let objApi = apiClient()
objApi.sendRequest(for: ProfileDetails.self,
endPoint:"api/user/profile/\(userId)",
method: .get,
token: objToken,
completion:
{(userResult: Result<ProfileDetails>) -> Void in
switch userResult
{
case .success(let value):
if value.respCode == "01" {
print(value.profile)
do {
//... ddo some taks like store response in local db or else
} catch let error as NSError {
// handle error
print(error)
}
}
else {
//do some task
}
break
case .failure(let error):
print(error)
break
}
})
}
我正在解码以下模型中的服务器响应
class ProfileDetails : Response, Decodable {
var appUpdate : AppUpdate?
var profile : Profile?
enum CodingKeys: String, CodingKey {
case profile = "profile"
case respCode = "resp_code"
case respMsg = "resp_msg"
}
public required convenience init(from decoder: Decoder) throws {
self.init()
let values = try decoder.container(keyedBy: CodingKeys.self)
self.profile = try values.decodeIfPresent(Profile.self, forKey: .profile)
self.respCode = try values.decodeIfPresent(String.self, forKey: .respCode)!
self.respMsg = try values.decodeIfPresent(String.self, forKey: .respMsg)
}
}
此代码无法处理来自服务器的401, 404
等错误响应。 所以我所寻找的,是这个API(转换URLRequest
)请求通用Alamofire
请求错误处理像401, 404
等。我已经安装Alamofire
吊舱。 是否有人开发了具有解码和错误处理功能的通用Alamofire
请求方法?
提前致谢 :)
Git 链接: https : //github.com/sahilmanchanda2/wrapper-class-for-alamofire
这是我的版本(使用Alamofire 5.0.2 ):
import Foundation
import Alamofire
class NetworkCall : NSObject{
enum services :String{
case posts = "posts"
}
var parameters = Parameters()
var headers = HTTPHeaders()
var method: HTTPMethod!
var url :String! = "https://jsonplaceholder.typicode.com/"
var encoding: ParameterEncoding! = JSONEncoding.default
init(data: [String:Any],headers: [String:String] = [:],url :String?,service :services? = nil, method: HTTPMethod = .post, isJSONRequest: Bool = true){
super.init()
data.forEach{parameters.updateValue($0.value, forKey: $0.key)}
headers.forEach({self.headers.add(name: $0.key, value: $0.value)})
if url == nil, service != nil{
self.url += service!.rawValue
}else{
self.url = url
}
if !isJSONRequest{
encoding = URLEncoding.default
}
self.method = method
print("Service: \(service?.rawValue ?? self.url ?? "") \n data: \(parameters)")
}
func executeQuery<T>(completion: @escaping (Result<T, Error>) -> Void) where T: Codable {
AF.request(url,method: method,parameters: parameters,encoding: encoding, headers: headers).responseData(completionHandler: {response in
switch response.result{
case .success(let res):
if let code = response.response?.statusCode{
switch code {
case 200...299:
do {
completion(.success(try JSONDecoder().decode(T.self, from: res)))
} catch let error {
print(String(data: res, encoding: .utf8) ?? "nothing received")
completion(.failure(error))
}
default:
let error = NSError(domain: response.debugDescription, code: code, userInfo: response.response?.allHeaderFields as? [String: Any])
completion(.failure(error))
}
}
case .failure(let error):
completion(.failure(error))
}
})
}
}
上述课程使用最新的 Alamofire 版本(截至 2020 年 2 月),该课程涵盖几乎所有 HTTP 方法,并可选择以应用程序/JSON 格式或普通格式发送数据。 使用这个类,您可以获得很大的灵活性,它会自动将响应转换为您的 Swift 对象。
看看这个类的init方法,它有:
data: [String,Any] = 在此您将放置表单数据。
headers: [String:String] = 在这个你可以发送你想和请求一起发送的自定义标头
url = 这里可以指定完整的url,如果你已经在Class中定义了baseurl,可以留空。 当您想使用第三方提供的 REST 服务时,它会派上用场。 注意:如果你正在填写 url 那么你应该下一个参数 service 应该是 nil
service: services = 它是在 NetworkClass 本身中定义的枚举。 这些用作端点。 查看init方法,如果url为nil但service不为nil,那么它会在base url的末尾追加一个完整的URL,示例将提供。
method: HTTPMethod = 在这里您可以指定请求应该使用哪种 HTTP 方法。
isJSONRequest = 默认设置为 true。 如果您想发送普通请求,请将其设置为 false。
在 init 方法中,您还可以指定要随每个请求发送的通用数据或标头,例如您的应用程序版本号、iOS 版本等
现在看看 execute 方法:它是一个通用函数,如果响应成功,它将返回您选择的 swift 对象。 它将以字符串形式打印响应,以防它无法将响应转换为您的 swift 对象。 如果响应代码不在 200-299 范围内,那么它将失败并为您提供完整的调试描述以获取详细信息。
用法:
说我们有以下结构:
struct Post: Codable{
let userId: Int
let id: Int
let title: String
let body: String
}
请注意 NetworkClass https://jsonplaceholder.typicode.com/ 中定义的基本 url
示例 1:发送内容类型为 Application/JSON 的 HTTP Post
let body: [String : Any] = ["title": "foo",
"body": "bar",
"userId": 1]
NetworkCall(data: body, url: nil, service: .posts, method: .post).executeQuery(){
(result: Result<Post,Error>) in
switch result{
case .success(let post):
print(post)
case .failure(let error):
print(error)
}
}
输出:
Service: posts
data: ["userId": 1, "body": "bar", "title": "foo"]
Post(userId: 1, id: 101, title: "foo", body: "bar")
HTTP 400 请求
NetworkCall(data: ["email":"peter@klaven"], url: " https://reqres.in/api/login ", method: .post, isJSONRequest: false).executeQuery(){ (result: Result ) 在切换结果{ case .success(let post): print(post) case .failure(let error): print(error) } }
输出:
Service: https://reqres.in/api/login
data: ["email": "peter@klaven"]
Error Domain=[Request]: POST https://reqres.in/api/login
[Request Body]:
email=peter%40klaven
[Response]:
[Status Code]: 400
[Headers]:
Access-Control-Allow-Origin: *
Content-Length: 28
Content-Type: application/json; charset=utf-8
Date: Fri, 28 Feb 2020 05:41:26 GMT
Etag: W/"1c-NmpazMScs9tOqR7eDEesn+pqC9Q"
Server: cloudflare
Via: 1.1 vegur
cf-cache-status: DYNAMIC
cf-ray: 56c011c8ded2bb9a-LHR
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
x-powered-by: Express
[Response Body]:
{"error":"Missing password"}
[Data]: 28 bytes
[Network Duration]: 2.2678009271621704s
[Serialization Duration]: 9.298324584960938e-05s
[Result]: success(28 bytes) Code=400 "(null)" UserInfo={cf-ray=56c011c8ded2bb9a-LHR, Access-Control-Allow-Origin=*, Date=Fri, 28 Feb 2020 05:41:26 GMT, expect-ct=max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct", Server=cloudflare, Etag=W/"1c-NmpazMScs9tOqR7eDEesn+pqC9Q", x-powered-by=Express, Content-Type=application/json; charset=utf-8, Content-Length=28, Via=1.1 vegur, cf-cache-status=DYNAMIC}
带有自定义标题
NetworkCall(data: ["username":"sahil.manchanda2@gmail.com"], headers: ["custom-header-key" : "custom-header-value"], url: " https://httpbin.org /post ", method: .post).executeQuery(){(result: Result) in switch result{ case .success(let data): print(data) case .failure(let error): print(error) } }
输出:
Service: https://httpbin.org/post
data: ["username": "sahil.manchanda2@gmail.com"]
{
"args": {},
"data": "{\"username\":\"sahil.manchanda2@gmail.com\"}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "br;q=1.0, gzip;q=0.9, deflate;q=0.8",
"Accept-Language": "en;q=1.0",
"Content-Length": "41",
"Content-Type": "application/json",
"Custom-Header-Key": "custom-header-value",
"Host": "httpbin.org",
"User-Agent": "NetworkCall/1.0 (sahil.NetworkCall; build:1; iOS 13.2.2) Alamofire/5.0.2",
"X-Amzn-Trace-Id": "Root=1-5e58a94f-fab2f24472d063f4991e2cb8"
},
"json": {
"username": "sahil.manchanda2@gmail.com"
},
"origin": "182.77.56.154",
"url": "https://httpbin.org/post"
}
typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode String but found a dictionary instead.", underlyingError: nil))
在最后一个示例中,您可以在最后看到 typeMismatch,我尝试在 executeQuery 中传递 [String:Any] 但由于 Any 未确认为可编码,因此我不得不使用 String。
我将 EVReflection 与 alamofire 一起使用,我认为这是最好的组合之一。
使用 Alamofire 的 URLRequestConvertible 协议。
这就是我所遵循的。
仅供参考。
为您的所有端点创建枚举并将该枚举确认为 URLRequestConvertible。
enum Router: URLRequestConvertible {
//your all endpoint
static var authToken = ""
case login([String:Any])
var route: Route {
switch self {
case .Login(let dict):
return Route(endPoint: "api/addimagedata", httpMethod: .post)
}
}
func asURLRequest() throws -> URLRequest {
var requestUrl = EnvironmentVariables.baseURL
if let queryparams = route.queryParameters {
requestUrl.appendQueryParameters(queryparams)
}
var mutableURLRequest = URLRequest(url: requestUrl.appendingPathComponent(route.endPath))
mutableURLRequest.httpMethod = route.method.rawValue
//FIXME:- Change the Userdefault Key
if Router.authToken.isEmpty, let token = UserDefaults.standard.string(forKey: "Key"), !token.isEmpty {
Router.authToken = token
}
//FIXME:- Set Mutable Request Accordingly
mutableURLRequest.setValue("Bearer \(Router.authToken)", forHTTPHeaderField: "Authorization")
mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Accept")
if route.method == .get {
return try Alamofire.URLEncoding.default.encode(mutableURLRequest, with: route.parameters)
}
return try Alamofire.JSONEncoding.default.encode(mutableURLRequest, with: route.parameters)
}
}
根据您的要求制作一个结构。
struct Route {
let endPath: String
let method: Alamofire.HTTPMethod
var parameters: Parameters?
var queryParameters : [String:String]?
var encoding: Alamofire.ParameterEncoding {
switch method {
case .post, .put, .patch, .delete:
return JSONEncoding()
default:
return URLEncoding()
}
}
}
现在创建一个通用函数,它接受 URLRequestConvertible 并在闭包中返回您的模型。 像这样的东西。
func GenericApiCallForObject<T : URLRequestConvertible, M : EVObject>(router : T, showHud : Bool = true ,responseModel : @escaping (M) -> ()) {
view.endEditing(true)
if !isConnectedToInternet {
showNetworkError()
return
}
if showhud ? showHud() : ()
Alamofire.request(router).responseObject { (response: DataResponse<M>) in
self.HandleResponseWithErrorForObject(response: response) { (isSuccess) in
if isSuccess {
if let value = response.result.value {
responseModel(value)
}
}
})
}
}
现在创建一个通用函数来接受您的响应并为您处理错误。 像这样的东西。
func HandleResponseWithErrorForObject<M : EVObject>(response : DataResponse<M>, isSuccess : @escaping (Bool) -> ()) {
print(response)
hideHud()
switch response.response?.statusCode ?? 0 {
case 200...299:
isSuccess(true)
case 401:
isSuccess(false)
showSessionTimeOutError()
case -1005,-1001,-1003:
break
default:
isSuccess(false)
// Parse your response and show error in some way.
}
}
现在终于知道怎么用了吧??! 事实上,现在它非常简单,只需两行代码,您就可以开始使用了。
GenericApiCallForObject(router: Router.Login(["xyz":"xyz"])) { (response : GeneralModel) in
print(response)
}
请注意,这仅在您收到对象响应时才有效。 如果有一个数组或字符串,您必须为此创建单独的函数,并且程序与上述相同。 如果成功,您只会得到响应,否则 HandleResponseWithErrorForObject 函数会自动为您处理。 此外,上述解释中可能缺少一些变量。
我正在分享我的 REST api 错误处理的特定部分。 它将在以下块内解码,您可能可以将其用作参考。
如您所见,获取代码并转换为枚举非常简单。 Alamofire 允许这样做,但这取决于您的库版本。 有时取决于你的 REST api 如何在内部处理错误,它们不能抛出代码,例如如果它的 Java 后端,它们可以封装异常。
public enum RESTError: Error {
case BadRequest(String, [String]?)
case InternalError(String)
case UnAuthorized(String, [String]?)
case NotFound(String)
case Success
/// <#Description#>
///
/// - Parameters:
/// - code: <#code description#>
/// - message: <#message description#>
/// - globalErrors: <#globalErrors description#>
/// - Returns: <#return value description#>
public static func fromCode(code: Int, message: String, globalErrors: [String]? = nil) -> RESTError {
switch code {
case 400: return RESTError.BadRequest(message, globalErrors)
case 401: return RESTError.UnAuthorized(message, globalErrors)
case 500: return RESTError.InternalError(message)
case 404: return RESTError.NotFound(message)
default: break
}
return RESTError.Success
}
}
Alamofire.request(urlRequest)
.validate(statusCode: 200...500)
.responseJSON(completionHandler: { (response: (DataResponse<Any>)) in
if let statusCode = response.response?.statusCode {
if statusCode != 200 {
// call handler errors function with specific message
if let arrayDictionary = response.result.value as? Dictionary<String,AnyObject> {
var error: RESTError?
if let code = arrayDictionary["status"] as? Int {
let message = arrayDictionary["message"] as! String
let globalErrors = arrayDictionary["globalErrors"] as? [String]
error = RESTError.fromCode(code: code, message: message, globalErrors: globalErrors)
} else {
// Build from error message without code.
let message = arrayDictionary["error_description"] as! String
let codeMsg = arrayDictionary["error"] as! String
let globalErrors = arrayDictionary["globalErrors"] as? [String]
if codeMsg == "invalid_token" && message.starts(with: "Access token expired") {
return
} else {
error = RESTError.fromCode(code: codeMsg, message: message, globalErrors: globalErrors)
}
}
if let _ = error {
errorHandler(error!)
} else {
errorHandler(RESTError.InternalError("Internal API rest error."))
}
} else {
errorHandler(RESTError.fromCode(code: statusCode, message: ""))
}
} else {
if let arrayDictionary = response.result.value as? Dictionary<String,AnyObject> {
handler(arrayDictionary)
}
}
} else {
if let error = response.error {
errorHandler(RESTError.InternalError(error.localizedDescription))
}
}
})
您可能需要这个使用 alamofilre 会话管理器来执行请求的函数。 您还可以将 cookie ant 标头等设置到此会话管理器,以便您将它们用于其余的请求。
import Alamofire
class NetworkManager : NSObject {
internal typealias SuccessCompletion = (Int?, Any?) -> Void?
internal typealias FailCompletion = (Int?, Error, Any?) -> Void?
var sessionManager : SessionManager!
var request : Request?
var headers : HTTPHeaders! = [:]
override init() {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
sessionManager = SessionManager(configuration: configuration)
}
func sendRequest(url: String?, method: String, parameters: [String: Any], success: SuccessCompletion?, fail: FailCompletion?){
var encoding : ParameterEncoding!
if HTTPMethod(rawValue: method) == HTTPMethod.post {
encoding = JSONEncoding.default
} else {
encoding = URLEncoding.default
}
request = sessionManager.request(url ?? "", method: HTTPMethod(rawValue: method)!, parameters: parameters, encoding: encoding, headers: headers)
.validate()
.responseData{response in
switch (response.result) {
case .success:
let statusCode = response.response?.statusCode
success?(statusCode, response.result.value)
self.request = nil
break
case .failure(let error):
let statusCode = response.response?.statusCode
fail?(statusCode, error, response.data)
self.request = nil
break
}
}
}
}
编辑
要添加标题,您只需添加这样的功能即可..
func updateJSONHeader(token: String) {
self.clearHeaders()
headers["AuthorizationToken"] = "\(token)"
}
饼干用
func setCookie(_ cookie : HTTPCookie?){
if let cookie = cookie {
HTTPCookieStorage.shared.setCookie(cookie)
}
}
清除标题
func clearHeaders(){
headers = [:]
}
请记住,它是一个单例类,因此每当您更改任何内容时,除非您的服务器进行一些更改,否则您仍然拥有配置,例如。 标题
最好的方法是使用 DataRequest 扩展创建自定义验证方法:
func customValidate() -> Self {
return self.validate { _, response, data -> Request.ValidationResult in
guard (400...599) ~= response.statusCode else { return .success(()) }
guard let data = data else { return .failure(MyAppGeneralError.generalResponseError) }
guard let errorResponse = try? JSONDecoder().decode(MyAppResponseError.self, from: data) else {
return .failure(MyAppGeneralError.generalResponseError)
}
if response.statusCode == 401 {
return .failure(MyAppGeneralError.unauthorizedAccessError(errorResponse))
}
return .failure(MyAppGeneralError.responseError(errorResponse))
}
}
使用具有通用功能的客户端,其中通用可使用我们的自定义验证进行解码。
class APIClient {
var session: Session
init(session: Session = Session.default) {
self.session = session
}
@discardableResult
func performRequest<T: Decodable>(request: URLRequestConvertible,
decoder: JSONDecoder = JSONDecoder(),
completion: @escaping (Result<T, AFError>) -> Void) -> DataRequest {
return AF.request(request).customValidate().responseDecodable(decoder: decoder, completionHandler: { (response: DataResponse<T, AFError>) in
completion(response.result)
})
}
func getProfile(userID: Int, _ completion: @escaping (Result<UserToken, AFError>) -> Void) {
performRequest(request: APIRouter.profile(userID: userID), completion: completion)
}
}
使用路由器 a:
enum APIRouter: URLRequestConvertible {
case profile(userId :Int)
static let baseURLString = "https://myserver.com"
var method: HTTPMethod {
switch self {
case .profile:
return .get
}
}
var path: String {
switch self {
case .profile(let userID):
return "profile/\(userID)"
}
}
var body: Parameters {
return [:]
}
// MARK: URLRequestConvertible
func asURLRequest() throws -> URLRequest {
let url = try APIRouter.baseURLString.asURL()
var urlRequest = URLRequest(url: url.appendingPathComponent(path))
urlRequest.httpMethod = method.rawValue
// Common Headers
urlRequest.setValue("application/json", forHTTPHeaderField: "Accept")
// Encode body
urlRequest = try JSONEncoding.default.encode(urlRequest, with: body)
return urlRequest
}
}
import Foundation
导入 UIKit 导入 Alamofire 导入 SwiftyJSON
类 AFWrapper: NSObject {
static let sharedInstance = AFWrapper()
//TODO :-
/* Handle Time out request alamofire */
func requestGETURL(_ strURL: String, success:@escaping (JSON) -> Void, failure:@escaping (Error) -> Void)
{
Alamofire.request(strURL).responseJSON { (responseObject) -> Void in
//print(responseObject)
if responseObject.result.isSuccess {
let resJson = JSON(responseObject.result.value!)
//let title = resJson["title"].string
//print(title!)
success(resJson)
}
if responseObject.result.isFailure {
let error : Error = responseObject.result.error!
failure(error)
}
}
}
func requestPOSTURL(_ strURL : String, params : [String : AnyObject]?, headers : [String : String]?, success:@escaping (JSON) -> Void, failure:@escaping (Error) -> Void){
Alamofire.request(strURL, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON { (responseObject) -> Void in
//print(responseObject)
if responseObject.result.isSuccess {
let resJson = JSON(responseObject.result.value!)
success(resJson)
}
if responseObject.result.isFailure {
let error : Error = responseObject.result.error!
failure(error)
}
}
}
}
这是我一直在努力的事情! 尚未完成,但可以解决您的问题。 你可以将它升级到任何你想要的。
类型别名
typealias Closure<T> = (T)->()
typealias JSON = [String: Any]
延期
extension JSONDecoder{
func decode<T : Decodable>(_ model : T.Type,
result : @escaping Closure<T>) ->Closure<Data>{
return { data in
if let value = try? self.decode(model.self, from: data){
result(value)
}
}
}
协议//MARK:- 协议 APIResponseProtocol
protocol APIResponseProtocol{
func responseDecode<T: Decodable>(to modal : T.Type,
_ result : @escaping Closure<T>) -> APIResponseProtocol
func responseJSON(_ result : @escaping Closure<JSON>) -> APIResponseProtocol
func responseFailure(_ error :@escaping Closure<String>)
}
请求:
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 300 // seconds
configuration.timeoutIntervalForResource = 500
alamofireManager = Alamofire.SessionManager(configuration: configuration)
func getRequest(forAPI api: String, params: JSON) -> APIResponseProtocol {
let responseHandler = APIResponseHandler()
var parameters = params
parameters["token"] = preference.string(forKey: USER_ACCESS_TOKEN)
alamofireManager.request(api,
method: .get,
parameters: parameters,
encoding: URLEncoding.default,
headers: nil)
.responseJSON { (response) in
print("Å api : ",response.request?.url ?? ("\(api)\(params)"))
switch response.result{
case .success(let value):
let json = value as! JSON
let error = json.string("error")
guard error.isEmpty else{
responseHandler.handleSuccess(value: value,data: response.data ?? Data())
case .failure(let error):
responseHandler.handleFailure(value: error.localizedDescription)
}
}
return responseHandler
}
响应处理程序:
类 APIResponseHandler : APIResponseProtocol{
init(){
}
var jsonSeq : Closure<JSON>?
var dataSeq : Closure<Data>?
var errorSeq : Closure<String>?
func responseDecode<T>(to modal: T.Type, _ result: @escaping Closure<T>) -> APIResponseProtocol where T : Decodable {
let decoder = JSONDecoder()
self.dataSeq = decoder.decode(modal, result: result)
return self
}
func responseJSON(_ result: @escaping Closure<JSON>) -> APIResponseProtocol {
self.jsonSeq = result
return self
}
func responseFailure(_ error: @escaping Closure<String>) {
self.errorSeq = error
}
func handleSuccess(value : Any,data : Data){
if let jsonEscaping = self.jsonSeq{
jsonEscaping(value as! JSON)
}
if let dataEscaping = dataSeq{
dataEscaping(data)
}
}
func handleFailure(value : String){
self.errorSeq?(value)
}
}
用法:
self?.apiInteractor?
.getRequest(forAPI: "https://maps.googleapis.com/maps/api/directions/json",
params: [
"origin" : "\(pickUpLatitude),\(pickUpLongitude)",
"destination" :"\(dropLatitude),\(dropLongitude)",
"mode" : "driving",
"units" : "metric",
"sensor" : "true",
"key" : "\(UserDefaults.value(for: .google_api_key) ?? "")"
])
.responseDecode(to: GoogleGeocode.self, { [weak self] (googleGecode) in
guard let welf = self,
let route = googleGecode.routes.first,
let leg = route.legs.first else{return}
welf.tripDetailModel?.arrivalFromGoogle = leg.duration.text ?? ""
welf.drawRoute(forRoute: route)
welf.calculateETA()
})
.responseJSON({ (json) in
debugPrint(json.description)
})
.responseFailure({ (error) in
debug(print: error)
})
只是代码的一部分,但尝试
let req = Alamofire.request(url, method: .get, parameters: nil)
然后您可以使用处理响应代码
req.response?.statusCode
并通过例如处理响应
req.responseString(completionHandler: <#T##(DataResponse<String>) -> Void#>)
or
req.responseJSON(completionHandler: <#T##(DataResponse<Any>) -> Void#>)
你在这里有很好的例子
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.