rch(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) } }
Alamofire.request(Router.search(query: "foo bar", page: 1)) // https://example.com/search?q=foo%20bar&offset=50
CRUD和授权
import Alamofire 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)" } }
Alamofire.request(Router.readUser("mattt"))
适配和重试请求
现在的大多数Web服务,都需要身份认证。现在比较常见的是OAuth。通常是需要一个access token来授权应用或者用户,然后才可以使用各种支持的Web服务。创建这些access token是比较麻烦的,当access token过期之后就比较麻烦了,我们需要重新创建一个新的。有许多线程安全问题要考虑。
RequestAdapter 和RequestRetrier 协议可以让我们更容易地为特定的Web服务创建一个线程安全的认证系统。
RequestAdapter
RequestAdapter 协议允许每一个SessionManager 的Request 在创建之前被检查和适配。一个非常特别的使用适配器方法是,在一个特定的认证类型,把Authorization header拼接到请求。
class AccessTokenAdapter: RequestAdapter { private let accessToken: String init(accessToken: String) { self.accessToken = accessToken } func adapt(_ urlRequest: URLRequest) throws -> URLRequest { var urlRequest = urlRequest if let urlString = urlRequest.url?.absoluteString, urlString.hasPrefix("https://httpbin.org") { urlRequest.setValue("Bearer " + accessToken, forHTTPHeaderField: "Authorization") } return urlRequest } }
let sessionManager = SessionManager() sessionManager.adapter = AccessTokenAdapter(accessToken: "1234") sessionManager.request("https://httpbin.org/get")
RequestRetrier
RequestRetrier 协议允许一个在执行过程中遇到error的请求被重试。当一起使用RequestAdapter 和RequestRetrier 协议时,我们可以为OAuth1、OAuth2、Basic Auth(每次请求API都要提供用户名和密码)甚至是exponential backoff重试策略创建资格恢复系统。下面的例子演示了如何实现一个OAuth2 access token的恢复流程。
免责声明:这不是一个全面的OAuth2解决方案。这仅仅是演示如何把RequestAdapter 和RequestRetrier 协议结合起来创建一个线程安全的恢复系统。
重申: 不要把这个例子复制到实际的开发应用中,这仅仅是一个例子。每个认证系统必须为每个特定的平台和认证类型重新定制。
class OAuth2Handler:
|