gpt4 book ai didi

ios - Alamofire 4 重试器和适配器无法看到更改的 accessToken

转载 作者:搜寻专家 更新时间:2023-10-31 19:27:26 26 4
gpt4 key购买 nike

我正在使用 alamofire 的重试器和适应协议(protocol)获取新的访问 token 。我能够获取一个新 token ,但有时当另一个线程正在调用相同的方法时,它不起作用,即使生成了新的访问 token ,请求也会失败。

我刚刚更改了示例,现在我正在使用同步请求来获取访问 token ,因为如果我知道 token 无效,我不想在 adapt 中发送额外的请求。

奇怪的是,当我打印失败请求的响应时,我看到该请求的 header 中仍然有旧 token 。我在这里缺少什么?

func isTokenValid() -> Bool {
return Date() < self.expiryTime
}

func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
var urlRequest = urlRequest
urlRequest = processRequest(urlRequest: urlRequest)
return urlRequest
}

func processRequest(urlRequest: URLRequest) -> URLRequest {
DDLogInfo("******access token : \(self.accessToken)***************")
DDLogInfo("***** expiry Time: \(self.expiryTime)***************")
var urlRequest = urlRequest
lock.lock(); defer { DDLogInfo( "Thread UnLocked ⚡️: \(Thread.current)\r" + "🏭: \(OperationQueue.current?.underlyingQueue?.label ?? "None")\r")
lock.unlock()
}
DDLogInfo( "Thread Locked ⚡️: \(Thread.current)\r" + "🏭: \(OperationQueue.current?.underlyingQueue?.label ?? "None")\r")

if !isTokenValid() {
let _ = self.refreshAccessToken()
}

urlRequest = self.appendToken(urlRequest: urlRequest)
DDLogInfo("here \(urlRequest)")
return urlRequest
}

func appendToken(urlRequest: URLRequest) -> URLRequest {
if let urlString = urlRequest.url?.absoluteString, urlString.hasPrefix(baseURLString) {
var urlRequest = urlRequest
DDLogInfo("token appended : \(self.accessToken)")
urlRequest.setValue(self.accessToken, forHTTPHeaderField: Constants.KeychainKeys.accessToken)
}
return urlRequest
}

// MARK: - RequestRetrier

func handleFailedRequest(_ completion: @escaping RequestRetryCompletion) {
requestsToRetry.append(completion)
if !isRefreshing {
lock.lock()
print( "Thread Locked⚡️: \(Thread.current)\r" + "🏭: \(OperationQueue.current?.underlyingQueue?.label ?? "None")\r")

let succeeded = self.refreshAccessToken()
self.requestsToRetry.forEach {
print("token fetched \(succeeded): \(self.accessToken)")
$0(succeeded, 0.0)
}
self.requestsToRetry.removeAll()
DDLogInfo( "Thread UnLocked⚡️: \(Thread.current)\r" + "🏭: \(OperationQueue.current?.underlyingQueue?.label ?? "None")\r")
lock.unlock()
}
}


func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {

if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401, request.retryCount < 3 {
handleFailedRequest(completion)
} else {
completion(false, 0.0)
}
}

func updateTokens (accessToken: String, refreshToken: String, accessTokenExpiresIn: Double) {
self.accessToken = accessToken
self.refreshToken = refreshToken
let expiryDate = Date(timeIntervalSinceNow: accessTokenExpiresIn - Constants.KeychainKeys.expirationBuffer)
AppSettings.sharedInstance.tokenExpiryTime = expiryDate
self.expiryTime = expiryDate
do {try keychainWrapper.save(values: ["accessToken": self.accessToken, "refreshToken": self.refreshToken])} catch {
DDLogError("unable to save accessToken")
}
}

// MARK: - Private - Refresh Tokens

fileprivate func refreshAccessToken() -> Bool {
DDLogInfo("^^^^^^^^")
Thread.callStackSymbols.forEach { DDLogInfo($0) }

var success = false
guard !isRefreshing else { return success }
let refreshRequest = URLRequestConfigurations.configRefreshProviderAgent(refreshToken: self.refreshToken)
let result = URLSession.shared.synchronousDataTask(with: refreshRequest)

self.isRefreshing = false
do {
if let data = result.0, let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String : Any] {
if let accessToken = json["accessToken"] as? String, let refreshToken = json["refreshToken"] as? String, let time = json["accessTokenExpiresIn"] as? Double {
updateTokens(accessToken: accessToken, refreshToken: refreshToken, accessTokenExpiresIn: time)
success = true
} else {
DDLogError("unable to find tokens/expiryInterval from refresh request")
}
} else {
DDLogError("unable to receive data from refresh request")
}
} catch {
DDLogError("unable to parse json response from refersh token request")
}
return success
}

最佳答案

您可以通过为网络事件创建单例类来检查吗?单例模式保证一个类只有一个实例被实例化。像这样:-

open class NetworkHelper {

class var sharedManager: NetworkHelper {
struct Static{
static let instance: NetworkHelper = NetworkHelper()
}
return Static.instance
}

.... Put you network call method here


}

关于ios - Alamofire 4 重试器和适配器无法看到更改的 accessToken,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50226406/

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