如何实现具有类似 asURLRequest() 的多个路由器
Posted
技术标签:
【中文标题】如何实现具有类似 asURLRequest() 的多个路由器【英文标题】:How to implement multiple Routers with similar asURLRequest() 【发布时间】:2021-09-23 19:42:32 【问题描述】:我一直在努力在我们的应用程序中重新实现一个健康的网络层,并且在许多教程/Alamofire 文档中都提到了路由器。该应用程序有很多端点,为了保持可读性,我想将它们分成它们的服务子集。这也被认为是一种最佳做法。
我实现的第一个端点工作得非常好,但是,当我创建另一个路由器时,asURLRequest() 函数几乎是重复的。唯一的区别可能是开关/外壳。否则几乎可以肯定是一样的。
要在 Kotlin 或 Java 中执行此操作,我将创建一个类并扩展调用 super 的函数。我不确定这在 Swift 中是如何工作的。
enum AuthenticationRouter: URLRequestConvertible
case login(username:String, password:String)
// MARK: - HTTPMethod
private var method: HTTPMethod
switch self
case .login:
return .get
// MARK: - Path
private var path: String
switch self
case .login:
return "users/login"
// MARK: - Parameters
private var parameters: Parameters?
switch self
case .login:
return nil
// MARK: - URLRequestConvertible
func asURLRequest() throws -> URLRequest
let url = try K.TestServer.baseURL.asURL()
var urlRequest = URLRequest(url: url.appendingPathComponent(path))
// HTTP Method
urlRequest.httpMethod = method.rawValue
// Common Headers
urlRequest.setValue(ContentType.json.rawValue, forHTTPHeaderField: HTTPHeaderField.acceptType.rawValue)
urlRequest.setValue(ContentType.json.rawValue, forHTTPHeaderField: HTTPHeaderField.contentType.rawValue)
switch self
case .login(let username, let password):
// Handle adjusting headers or request as needed
default: ()
// Parameters
if let parameters = parameters
do
urlRequest.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: [])
catch
throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error))
return urlRequest
【问题讨论】:
如何使用继承/协议?创建实现 asUrlRequest() 函数的基本路由器类/协议?每个其他路由器都有自己的参数/符合 Alamofire 协议的其他部分 【参考方案1】:这是我使用的旧代码。我会将基类更改为协议,并继续使用符合该协议的枚举,我更喜欢它。
import Alamofire
protocol API
var method: HTTPMethod get
var encoding: ParameterEncoding? get
var parameters: Parameters get
var headers: HTTPHeaders get
var timeout:TimeInterval get
var path: String get
var baseUrl: String get
class Router: API
var method: HTTPMethod .get
var encoding: ParameterEncoding? JSONEncoding.default
var parameters: Parameters
let params = Parameters()
return params
var headers: HTTPHeaders
let headers = HTTPHeaders()
// TODO - add defualt headers if needed
return headers
var timeout: TimeInterval
#if DEBUG
return 120
#else
return 30
#endif
var path: String
fatalError("Must be overridden in subclass")
var baseUrl: String Consts.serverUrl
extension Router: URLRequestConvertible
open func asURLRequest() throws -> URLRequest
guard let baseURL = URL(string: baseUrl) else throw someError
let appendedURL = baseURL.appendingPathComponent(path)
let urlRequest = try URLRequest(url: appendedURL, method: method)
guard let encoder = encoding else throw someError
var eUrlRequest = try encoder.encode(urlRequest, with: parameters)
eUrlRequest.timeoutInterval = timeout
headers.forEach eUrlRequest.addValue($0.value, forHTTPHeaderField: $0.name)
return eUrlRequest
然后是 UserRouter 的示例
import Alamofire
final class UserRouter: Router
enum Endpoint
case signIn(userName: String, password: String)
let endpoint: Endpoint
init(endpoint: Endpoint)
self.endpoint = endpoint
override var method: HTTPMethod
.get
override var parameters: Parameters
var params = super.parameters
switch endpoint
case .signIn(let userName, let password):
params[“login”] = [“username”: userName, “password”: password]
return params
override var path: String
switch endpoint
case .signIn:
return "/signIn"
这样,asUrlRequest() 函数将在整个代码中使用(;Alamofire.Session().request() 函数将接受每个路由器。
此外,还有一个很棒的开源抽象可以在 Alamofire 上进行类似的工作。莫亚-https://github.com/Moya/Moya。 它开箱即用地支持 Combine 和 RxSwift
【讨论】:
以上是关于如何实现具有类似 asURLRequest() 的多个路由器的主要内容,如果未能解决你的问题,请参考以下文章
如何在 maximo 中隐藏具有类似于银行帐号的特殊字符的字段值