iOS集成Amazon Cognito:未登录时跳转启动页而非登录页问题
嘿,这个问题我之前帮人处理过,其实调整起来没那么复杂,核心是把你的启动页接入到Cognito的认证协议流程里,而不是直接返回登录页。给你一步步拆解怎么做:
核心思路
AWSCognitoIdentityInteractiveAuthenticationDelegate要求返回的VC必须遵循AWSCognitoIdentityPasswordAuthentication协议,那我们就让启动页VC来遵循这个协议,把它作为认证流程的入口,再在启动页里处理登录/注册的跳转逻辑,同时把Cognito的认证回调传递给后续的登录/注册页面,完成整个流程。
步骤1:让启动页遵循认证协议
首先给你的启动页VC添加协议遵循,同时实现两个核心协议方法,还要保存Cognito的回调对象:
class LaunchViewController: UIViewController, AWSCognitoIdentityPasswordAuthentication { // 保存Cognito的认证回调,登录/注册完成后必须调用它 var passwordAuthenticationCompletion: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>? var lastKnownUsername: String? // 协议方法:Cognito触发认证时调用,我们在这里跳转到登录页 func getPasswordAuthenticationDetails(_ authenticationInput: AWSCognitoIdentityPasswordAuthenticationInput, passwordAuthenticationCompletion: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>) { self.passwordAuthenticationCompletion = passwordAuthenticationCompletion self.lastKnownUsername = authenticationInput.lastKnownUsername // 跳转到登录VC,把回调和上次的用户名传递过去 let loginVC = LoginViewController() loginVC.authCompletion = passwordAuthenticationCompletion loginVC.preFillUsername = lastKnownUsername navigationController?.pushViewController(loginVC, animated: true) } // 协议方法:认证步骤完成时调用(处理成功/错误) func didCompletePasswordAuthenticationStepWithError(_ error: Error?) { if let authError = error { // 这里可以在启动页显示认证错误提示,比如弹个Alert let alert = UIAlertController(title: "登录失败", message: authError.localizedDescription, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) present(alert, animated: true) } else { // 认证成功!跳转到你的主页面 let mainTabBar = MainTabBarController() UIApplication.shared.keyWindow?.rootViewController = mainTabBar } } // 启动页的登录按钮点击事件 @IBAction func loginButtonTapped(_ sender: UIButton) { // 如果用户主动点登录,直接触发跳转逻辑 let loginVC = LoginViewController() loginVC.authCompletion = passwordAuthenticationCompletion loginVC.preFillUsername = lastKnownUsername navigationController?.pushViewController(loginVC, animated: true) } // 启动页的注册按钮点击事件 @IBAction func registerButtonTapped(_ sender: UIButton) { let registerVC = RegisterViewController() registerVC.onRegisterSuccess = { [weak self] username, password in // 注册成功后,手动给Cognito传递认证信息,触发登录流程 let authDetails = AWSCognitoIdentityPasswordAuthenticationDetails(username: username, password: password) self?.passwordAuthenticationCompletion?.set(result: authDetails) // 返回启动页,等待Cognito处理结果 self?.navigationController?.popViewController(animated: true) } navigationController?.pushViewController(registerVC, animated: true) } }
步骤2:修改AppDelegate的startPasswordAuthentication方法
现在不再返回登录VC,而是返回你的启动页VC,记得如果启动页需要导航的话,包装成导航控制器:
func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication { let storyboard = UIStoryboard(name: "Main", bundle: nil) let launchVC = storyboard.instantiateViewController(withIdentifier: "LaunchViewController") as! LaunchViewController // 把启动页嵌入导航控制器,方便后续跳转登录/注册 let navController = UINavigationController(rootViewController: launchVC) UIApplication.shared.keyWindow?.rootViewController = navController // 注意:返回的是遵循协议的启动页VC,不是导航控制器 return launchVC }
步骤3:完善登录VC的逻辑
登录VC需要接收回调和预填用户名,用户输入完成后调用回调告知Cognito:
class LoginViewController: UIViewController { var authCompletion: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>? var preFillUsername: String? @IBOutlet weak var usernameField: UITextField! @IBOutlet weak var passwordField: UITextField! override func viewDidLoad() { super.viewDidLoad() // 预填上次登录的用户名 usernameField.text = preFillUsername } @IBAction func confirmLoginTapped(_ sender: UIButton) { guard let username = usernameField.text?.trimmingCharacters(in: .whitespaces), !username.isEmpty, let password = passwordField.text?.trimmingCharacters(in: .whitespaces), !password.isEmpty else { // 提示用户输入完整信息 let alert = UIAlertController(title: "提示", message: "请输入用户名和密码", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) present(alert, animated: true) return } // 把用户输入的信息传递给Cognito let authDetails = AWSCognitoIdentityPasswordAuthenticationDetails(username: username, password: password) authCompletion?.set(result: authDetails) // 返回启动页,等待认证结果回调 navigationController?.popViewController(animated: true) } }
关键注意点
- 回调对象不能丢:
passwordAuthenticationCompletion是连接你的UI和Cognito认证流程的核心,一定要妥善保存,登录/注册完成后必须调用它的set(result:)或set(error:)方法。 - 注册后的处理:如果用户选择注册,注册成功后需要手动创建
AWSCognitoIdentityPasswordAuthenticationDetails并传递给回调,这样Cognito会自动完成后续的登录认证步骤。 - 错误处理:在
didCompletePasswordAuthenticationStepWithError方法里处理认证失败的情况,给用户友好的提示。
这样调整后,当用户未登录时,Cognito会自动跳转到你的启动页,用户可以自由选择登录或注册,整个认证流程也能和Cognito完美对接啦。
内容的提问来源于stack exchange,提问作者Jon Sherman
相关产品推荐
相关产品推荐

