Swift同步问题:调用getMedicalData前idToken未被bearerToken设置
问题描述
我是Swift新手,bearerToken()函数用来更新getMedicalData()需要的idToken变量,但现在getMedicalData()会在bearerToken()完成idToken更新前就执行,导致它拿到的是空的idToken。怎么实现同步,让getMedicalData()等bearerToken()完全执行完再运行?
原调用代码
func login(username: String, password: String) { _ = Amplify.Auth.signIn( username: username, password: password ) { [weak self] result in switch result { case .success(let signInResult): print(SignInResult.self) if signInResult.isSignedIn { // 调用两个函数 TokenManager.shared.bearerToken() getMedicalData() DispatchQueue.main.async { self?.getCurrentAuthUser() } } case .failure(let error): print("Login error:", error) } } }
原bearerToken()函数
func bearerToken() { _ = Amplify.Auth.fetchAuthSession { result in switch result { case .success(let session): if(session.isSignedIn) { if let sess = session as? AWSAuthCognitoSession { let result = sess.getCognitoTokens() switch result { case .success(let tokens): self.idToken = String(tokens.idToken) self.refreshToken = tokens.refreshToken case .failure(let error): print("Fetch user tokens failed with error \(error)") } } } case .failure(let error): print("Fetch session failed with error \(error)") } } }
解决方案
方法1:给bearerToken()添加完成回调闭包
修改bearerToken(),让它在获取到token后触发传入的闭包,确保getMedicalData()在token更新完成后执行。
修改后的bearerToken():
func bearerToken(completion: @escaping () -> Void) { _ = Amplify.Auth.fetchAuthSession { result in switch result { case .success(let session): if(session.isSignedIn) { if let sess = session as? AWSAuthCognitoSession { let result = sess.getCognitoTokens() switch result { case .success(let tokens): self.idToken = String(tokens.idToken) self.refreshToken = tokens.refreshToken // 拿到token后执行回调 completion() case .failure(let error): print("Fetch user tokens failed with error \(error)") completion() } } else { completion() } } else { completion() } case .failure(let error): print("Fetch session failed with error \(error)") completion() } } }
修改login函数的调用逻辑:
func login(username: String, password: String) { _ = Amplify.Auth.signIn( username: username, password: password ) { [weak self] result in switch result { case .success(let signInResult): print(SignInResult.self) if signInResult.isSignedIn { // 等待token获取完成后再执行后续逻辑 TokenManager.shared.bearerToken { self?.getMedicalData() DispatchQueue.main.async { self?.getCurrentAuthUser() } } } case .failure(let error): print("Login error:", error) } } }
方法2:使用Async/Await(Swift 5.5及以上版本)
这种写法更简洁易读,利用Swift的异步语法实现等待逻辑。
修改后的bearerToken()异步函数:
func bearerToken() async { do { let session = try await Amplify.Auth.fetchAuthSession() if session.isSignedIn, let sess = session as? AWSAuthCognitoSession { let tokens = try sess.getCognitoTokens().get() self.idToken = String(tokens.idToken) self.refreshToken = tokens.refreshToken } } catch { print("Fetch session or tokens failed with error \(error)") } }
修改login函数的调用逻辑:
func login(username: String, password: String) { _ = Amplify.Auth.signIn( username: username, password: password ) { [weak self] result in switch result { case .success(let signInResult): print(SignInResult.self) if signInResult.isSignedIn { // 用Task包裹异步逻辑,等待token获取完成 Task { await TokenManager.shared.bearerToken() self?.getMedicalData() DispatchQueue.main.async { self?.getCurrentAuthUser() } } } case .failure(let error): print("Login error:", error) } } }
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

