gpt4 book ai didi

swift - 如何处理等待嵌套 URLSession 完成的情况

转载 作者:行者123 更新时间:2023-11-30 10:59:20 25 4
gpt4 key购买 nike

我有一个函数可以在 URLSession 上提供一个层。调用此函数时,我想检查当前访问 token 是否已过期,如果已过期,我将暂停当前调用,进行调用以请求新 token ,替换钥匙串(keychain)中的现有条目,然后继续电话。

func profile(with endpoint: ProfilesEndpoint, method: HTTPMethod, body: String?, headers: [String: String]?, useAuthToken: Bool = true, completion: @escaping (Either<ProfileResponse>) -> Void) {
var request = endpoint.request
request.httpMethod = method.rawValue

if let body = body {
request.httpBody = body.data(using: .utf8)
}

if useAuthToken {
if !AuthService.shared.isTokenValid {
let group = DispatchGroup()
group.enter()
OAuthService.shared.requestRefreshToken()
group.leave()
}

let (header, token) = AuthService.shared.createAuthHeaderForNetworkRequest()
request.addValue(token, forHTTPHeaderField: header)
}

if let headers = headers {
for (key, value) in headers {
request.addValue(value, forHTTPHeaderField: key)
}
}

execute(with: request, completion: completion)
}

存在用于处理钥匙串(keychain)的机制,因此请假定该机制已就位。

请求新 token 的函数如下所示

func requestRefreshToken() -> Void {

if let refreshToken = KeychainWrapper.standard.string(forKey: "RefreshToken") {

var postBody = "grant_type=\(refreshTokenGrantType)&"
postBody += "client_id=\(clientId)&"
postBody += "refresh_token=\(refreshToken)&"

let additionalHeaders = [
"Content-Type": "application/x-www-form-urlencoded;"
]

APIClient.shared.identity(with: .token, method: .post, body: postBody, headers: additionalHeaders, useAuthToken: false) { either in
switch either {
case .success(let results):
guard let accessToken = results.accessToken, let refreshToken = results.refreshToken else { return }
AuthService.shared.addTokensToKeyChain(tokens: ["AccessToken": accessToken, "RefreshToken": refreshToken])
case .error(let error):
print("Error:", error)
}
}
}
}

我期待执行在这里暂停

     group.enter()
OAuthService.shared.requestRefreshToken()
group.leave()

然而事实并非如此。

如何在完成函数的其余部分之前等待此调用完成?

最佳答案

添加到您的 requestRefreshToken 方法完成处理程序中,该处理程序将在您的 token 请求完成时执行

func requestRefreshToken(_ completion: @escaping () -> Void) {

if let refreshToken = KeychainWrapper.standard.string(forKey: "RefreshToken") {

var postBody = "grant_type=\(refreshTokenGrantType)&"
postBody += "client_id=\(clientId)&"
postBody += "refresh_token=\(refreshToken)&"

let additionalHeaders = [
"Content-Type": "application/x-www-form-urlencoded;"
]

APIClient.shared.identity(with: .token, method: .post, body: postBody, headers: additionalHeaders, useAuthToken: false) { either in

switch either {
case .success(let results):
guard let accessToken = results.accessToken, let refreshToken = results.refreshToken else {
completion()
return
}
AuthService.shared.addTokensToKeyChain(tokens: ["AccessToken": accessToken, "RefreshToken": refreshToken])
case .error(let error):
print("Error:", error)
}

completion()
}
}
}

然后将 dispatchGroup 保留在闭包中,并添加 group.wait() (在调用请求方法之后)用于暂停当前线程,直到组的任务完成

group.enter()
OAuthService.shared.requestRefreshToken {
group.leave()
}
group.wait()

注意:您可以在完成中添加 bool 参数来检查 token 请求是否成功

关于swift - 如何处理等待嵌套 URLSession 完成的情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53583627/

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