Alamofire是可用于iOS和Mac项目的流行框架。 这里来讲一下如何使用Alamofire实现token的签名和在token过期刷新token后进行网络请求的重试。
-
创建RequestAdapter和RequestRetrier
final class RequestInterceptor: Alamofire.RequestInterceptor {
func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) { guard urlRequest.url?.absoluteString.hasPrefix(BaseURL) == true else { /// 如果这个请求不需要签名则直接进行请求 return completion(.success(urlRequest)) } var urlRequest = urlRequest /// 使用access token来进行签名 urlRequest.setValue(你缓存的token, forHTTPHeaderField: "Authorization") urlRequest.setValue("在这里加一些服务器需要收集的设备信息的键值对", forHTTPHeaderField: "User-Agent") urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") completion(.success(urlRequest)) } func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) { guard let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 else { /// 这个请求没有因为401token过期 /// 则进行原始请求,不重试 return completion(.doNotRetryWithError(error)) } /// 401token过期,则调用刷新请求的方法 HpptClient.share.refreshToken { (complete) in if complete { /// 刷新token成功后过1秒进行重试请求 completion(.retryWithDelay(1)) } else { /// 刷新token失败放弃重试 return completion(.doNotRetryWithError(error)) } } }}
-
创建自定义Session
class SessionManager: NSObject { static let share: SessionManager = SessionManager()
var sessionManager: Session! fileprivate let configuration = URLSessionConfiguration.default override init() { super.init() configSession() } final func configSession() { configuration.timeoutIntervalForRequest = 15 // 15s超时 sessionManager = Session(configuration: configuration, interceptor: RequestInterceptor()) }}
-
使用配置好的Session进行网络请求
LDSessionManager.share.sessionManager.request("请求地址", method: 方法类型, parameters: 请求参数, encoding: JSONEncoding.default) .validate(statusCode: 200..<300) .validate(contentType: ["application/json"]) .responseData { response in switch response.result { case let .success(value): let dataJson = JSON(value) printD("response = (dataJson)") case let .failure(error): printD(error) } }
参考文献: