用于更整洁和灵活的类型安全路由的 Alamofire's URLRequestConvertible
的替代品。
这是一个来自 Alamofire 文档的 URLRequestConvertible
的示例
enum Router: URLRequestConvertible {
case createUser(parameters: Parameters)
case readUser(username: String)
case updateUser(username: String, parameters: Parameters)
case destroyUser(username: String)
static let baseURLString = "https://example.com"
var method: HTTPMethod {
switch self {
case .createUser:
return .post
case .readUser:
return .get
case .updateUser:
return .put
case .destroyUser:
return .delete
}
}
var path: String {
switch self {
case .createUser:
return "/users"
case .readUser(let username):
return "/users/\(username)"
case .updateUser(let username, _):
return "/users/\(username)"
case .destroyUser(let username):
return "/users/\(username)"
}
}
// MARK: URLRequestConvertible
func asURLRequest() throws -> URLRequest {
let url = try Router.baseURLString.asURL()
var urlRequest = URLRequest(url: url.appendingPathComponent(path))
urlRequest.httpMethod = method.rawValue
switch self {
case .createUser(let parameters):
urlRequest = try URLEncoding.default.encode(urlRequest, with: parameters)
case .updateUser(_, let parameters):
urlRequest = try URLEncoding.default.encode(urlRequest, with: parameters)
default:
break
}
return urlRequest
}
}
一眼看去并不容易理解这里正在发生什么,对吧?这是因为 URL 请求的配置散布在整个实现中,还导致了多个 switch
语句。当使用 URLRequestConfigurable
编写相同的示例时,它看起来是这样的
enum Router: URLRequestConfigurable {
case createUser(parameters: Parameters)
case readUser(username: String)
case updateUser(username: String, parameters: Parameters)
case destroyUser(username: String)
static let baseURLString = "http://example.com"
// MARK: URLRequestConfigurable
var urlRequestConfiguration: URLRequestConfiguration {
switch self {
case .createUser(let parameters):
return URLRequestConfiguration(url: "\(Router.baseURLString)/users",
method: .post,
parameters: parameters,
encoding: URLEncoding.default)
case .readUser(let username):
return URLRequestConfiguration(url: "\(Router.baseURLString)/users/\(username)",
method: .get)
case .updateUser(let username, let parameters):
return URLRequestConfiguration(url: "\(Router.baseURLString)/users/\(username)",
method: .put,
parameters: parameters,
encoding: URLEncoding.default)
case .destroyUser(let username):
return URLRequestConfiguration(url: "\(Router.baseURLString)/users/\(username)",
method: .delete)
}
}
}
更有结构性和可读性,对吧?使用 URLRequestConfigurable
,URL 请求的配置必须声明在一个地方,并且只在一个地方声明。这导致了所有 Routers 的干净和一致的外观。
此外请注意,从版本 1.1 开始,除了 url
以外,所有值如果不需要可以省略,这将进一步减少使用的行数。
让我们看一下另一个来自 Alamofire 的例子
enum Router: URLRequestConvertible {
case search(query: String, page: Int)
static let baseURLString = "https://example.com"
static let perPage = 50
// MARK: URLRequestConvertible
func asURLRequest() throws -> URLRequest {
let result: (path: String, parameters: Parameters) = {
switch self {
case let .search(query, page) where page > 0:
return ("/search", ["q": query, "offset": Router.perPage * page])
case let .search(query, _):
return ("/search", ["q": query])
}
}()
let url = try Router.baseURLString.asURL()
let urlRequest = URLRequest(url: url.appendingPathComponent(result.path))
return try URLEncoding.default.encode(urlRequest, with: result.parameters)
}
}
再次,您会看到示例如何被转换成一些更加悦目的东西,使用了 URLRequestConfigurable
enum Router: URLRequestConfigurable {
case Search(query: String, page: Int)
static let baseURLString = "http://example.com"
static let perPage = 50
// MARK: URLRequestConfigurable
var urlRequestConfiguration: URLRequestConfiguration {
switch self {
case .Search(let query, let page) where page > 1:
return URLRequestConfiguration(url: "\(Router.baseURLString)/search",
method: .get,
parameters: ["q": query, "offset": Router.perPage * page],
encoding: URLEncoding.default)
case .Search(let query, _):
return URLRequestConfiguration(url: "\(Router.baseURLString)/search",
method: .get,
parameters: ["q": query],
encoding: URLEncoding.default)
}
}
}
使用 URLRequestConfigurable
就像让你的 Routers 遵守 URLRequestConfigurable
协议一样简单。然后您可以像以前一样使用 Alamofire
来执行请求。
Alamofire.SessionManager.default.request(Router.get())
.responseJSON { response in
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
要运行示例项目,克隆仓库,并首先从 Example 目录运行 pod install
。
如果您想从 GiantBomb 获取结果(可选),您需要创建自己的 GiantBomb API 密钥 这里。
AlamofireURLRequestConfigurable 可通过 CocoaPods 获取。要安装它,只需将以下行添加到您的 Podfile 中:
Swift 3.0
pod 'AlamofireURLRequestConfigurable', '~> 1.1'
Swift 2.x
pod 'AlamofireURLRequestConfigurable', '1.0.1'
George Marmaridis
URLRequestConfigurable遵循MIT许可。更多信息请参见license文件。