gpt4 book ai didi

ios - Alamofire 5 调整和重试请求

转载 作者:行者123 更新时间:2023-12-04 19:15:11 26 4
gpt4 key购买 nike

我正在尝试使用 Alamofire 5.0.0-beta.3 实现我的 OAuth2 流程。正如我所看到的,文档仍然适用于 github 页面中所述的 Alamofire 4。

我正在尝试按照 Alamofire 4 的文档制作 Oauth2 处理程序。随着类名的更改,我在制作时完全迷失了方向。

这是我遵循的代码:

class OAuth2Handler: RequestAdapter, RequestRetrier {
private typealias RefreshCompletion = (_ succeeded: Bool, _ accessToken: String?, _ refreshToken: String?) -> Void

private let sessionManager: SessionManager = {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders

return SessionManager(configuration: configuration)
}()

private let lock = NSLock()

private var clientID: String
private var baseURLString: String
private var accessToken: String
private var refreshToken: String

private var isRefreshing = false
private var requestsToRetry: [RequestRetryCompletion] = []

// MARK: - Initialization

public init(clientID: String, baseURLString: String, accessToken: String, refreshToken: String) {
self.clientID = clientID
self.baseURLString = baseURLString
self.accessToken = accessToken
self.refreshToken = refreshToken
}

// MARK: - RequestAdapter

func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
if let urlString = urlRequest.url?.absoluteString, urlString.hasPrefix(baseURLString) {
var urlRequest = urlRequest
urlRequest.setValue("Bearer " + accessToken, forHTTPHeaderField: "Authorization")
return urlRequest
}

return urlRequest
}

// MARK: - RequestRetrier

func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
lock.lock() ; defer { lock.unlock() }

if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 {
requestsToRetry.append(completion)

if !isRefreshing {
refreshTokens { [weak self] succeeded, accessToken, refreshToken in
guard let strongSelf = self else { return }

strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() }

if let accessToken = accessToken, let refreshToken = refreshToken {
strongSelf.accessToken = accessToken
strongSelf.refreshToken = refreshToken
}

strongSelf.requestsToRetry.forEach { $0(succeeded, 0.0) }
strongSelf.requestsToRetry.removeAll()
}
}
} else {
completion(false, 0.0)
}
}

// MARK: - Private - Refresh Tokens

private func refreshTokens(completion: @escaping RefreshCompletion) {
guard !isRefreshing else { return }

isRefreshing = true

let urlString = "\(baseURLString)/oauth2/token"

let parameters: [String: Any] = [
"access_token": accessToken,
"refresh_token": refreshToken,
"client_id": clientID,
"grant_type": "refresh_token"
]

sessionManager.request(urlString, method: .post, parameters: parameters, encoding: JSONEncoding.default)
.responseJSON { [weak self] response in
guard let strongSelf = self else { return }

if
let json = response.result.value as? [String: Any],
let accessToken = json["access_token"] as? String,
let refreshToken = json["refresh_token"] as? String
{
completion(true, accessToken, refreshToken)
} else {
completion(false, nil, nil)
}

strongSelf.isRefreshing = false
}
}
}

这是如何将它用于 alamofire 4:
let baseURLString = "https://some.domain-behind-oauth2.com"

let oauthHandler = OAuth2Handler(
clientID: "12345678",
baseURLString: baseURLString,
accessToken: "abcd1234",
refreshToken: "ef56789a"
)

let sessionManager = SessionManager()
sessionManager.adapter = oauthHandler
sessionManager.retrier = oauthHandler

let urlString = "\(baseURLString)/some/endpoint"

sessionManager.request(urlString).validate().responseJSON { response in
debugPrint(response)
}

这是我遵循的链接来实现这一点。
https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#adapting-and-retrying-requests

最佳答案

看看这样的事情。

 struct EnvironmentInterceptor: RequestInterceptor {

func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest>) -> Void) {
var adaptedRequest = urlRequest
guard let token = AtraqService.shared.user?.token.accessToken else {
completion(.success(adaptedRequest))
return
}
adaptedRequest.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
completion(.success(adaptedRequest))
}

func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) {
if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 {
//get token
}
}
}

然后
        Session(configuration: configuration,  interceptor: EnvironmentInterceptor())

最后
request().validate().response...

关于ios - Alamofire 5 调整和重试请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55240842/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com