iOS应用程序中更好的使用路由—Swift
译:
在这篇文章中,我将讨论我之前在程序开发中使用的可以让iOS程序更加健壮的重用类。最近,我需要一个导航路由类来解决网络请求不同类型的URL,;例如:.GET .POST .PUT DELETE HTTP等等。
用一个单独的类来处理网络任务很👍,所以要自定义路由,这是基于Alamofire实现的。

什么是路由
路由是一种面向对象的方法来处理API / Microservice urls,但是他本身用枚举的形式。也就是采用枚举中的URL请求方法进行网络请求,无缝的同意和简化了网络路由。
参考文章:如何为Alamofire创建路由
创建路由协议
首先创建一个RouterProtocol
协议,用来兼容REST的四种请求方法(get、post、update、destroy)。
// MARK: - Router
protocol RouterProtocol {
var apiType: ApiType { get set }
func post() -> String
func get(identifier: String) -> String
func update(identifier: String) -> String
func destroy(identifier: String) -> String
}
struct AccountsRouter: RouterProtocol {
var apiType = ApiType.Accounts
func post() -> String { return apiType.route }
func get(identifier: String) -> String { return "\(apiType.route)/\(identifier)" }
func update(identifier: String) -> String { return "\(apiType.route)/\(identifier)" }
func destroy(identifier: String) -> String { return "\(apiType.route)/\(identifier)" }
}
然后定义一个Router
的枚举:
-
首先,遵守
RouterProtocol
,调用方法; -
Router
枚举必须是泛型,用以接收所用遵守RouterProtocol
的结构体; -
为四种接收方法(.GET .POST .PUT .DELETE)定义方法、路径和路由属性;
-
创建
NSMutableURLRequest
的属性URLRequest
,用来添加通用的配置,比如方法名、默认请求头、用户token等等; -
最后使用
Alamofire
的参数编码进行编码。//
// Router.swift
//
// Created by Seyhun Akyürek on 01/10/2016.
// Copyright © 2016 seyhunak. All rights reserved.
//
import Foundation
import Alamofire// MARK: - Router
protocol RouterProtocol {
var apiType: ApiType { get set }
func post() -> String
func get(identifier: String) -> String
func update(identifier: String) -> String
func destroy(identifier: String) -> String
}enum Router<T where T: RouterProtocol>: URLRequestConvertible {
case post(T, [String: AnyObject]) case get(T, String) case update(T, String, [String: AnyObject]) case destroy(T, String) var method: Alamofire.Method { switch self { case .post: return .POST case .get: return .GET case .update: return .PUT case .destroy: return .DELETE } } var path: NSURL { switch self { case .post(let object, _): return object.apiType.path case .get(let object): return object.0.apiType.path case .update(let object): return object.0.apiType.path case .destroy(let object): return object.0.apiType.path } } var route: String { switch self { case .post(let object, _): return object.post() case .get(let object, let identifier): return object.get(identifier) case .update(let object, let identifier, _): return object.update(identifier) case .destroy(let object, let identifier): return object.destroy(identifier) } } // MARK: - URLRequestConvertible var URLRequest: NSMutableURLRequest { let task = NSURLSession.sharedSession().dataTaskWithURL(path) { (data, response, error) in if error != nil { return } } task.resume() let mutableURLRequest = NSMutableURLRequest(URL: path.URLByAppendingPathComponent(route)) mutableURLRequest.HTTPMethod = method.rawValue mutableURLRequest.timeoutInterval = NSTimeInterval(10 * 1000) if let token = oauthToken { mutableURLRequest.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") mutableURLRequest.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") } switch self { case .post(_, let parameters): return Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: parameters).0 case .update(_, _, let parameters): return Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: parameters).0 default: return mutableURLRequest } } }
应用
使用Router
相当简单,只要在你的ApiManager
中定义一个方法:
//MARK: - Account
func getAccounts(accountRequest: AccountsRequest, completion: (accountsResponse: AccountsResponse) -> ()) -> Request {
weak var weakSelf = self
weakSelf?.errorManager.handleReachability()
store.dispatch(LoadingShowAction(type: .Normal))
return manager.request(Router.get(AccountsRouter(), accountRequest.accountId!).URLRequest)
.validate()
.responseObject {(response: Result<AccountsResponse, NSError>) in
self.handleResponse(response, completion: { (accountsResponse) in
store.dispatch(LoadingHideAction())
completion(accountsResponse: accountsResponse)
})
}
}
github:Router