UserDefaults 自动登录问题

Posted

技术标签:

【中文标题】UserDefaults 自动登录问题【英文标题】:UserDefaults Auto-Login trouble 【发布时间】:2020-09-02 19:00:23 【问题描述】:

我已经尽一切努力让用户通过 UserDefaults 保持登录状态。但是,每次我登录时,关闭应用程序并再次打开它,应用程序都会恢复到登录屏幕。我曾尝试使用其他类似问题的解决方案,但都没有奏效。

以下是点击“登录”按钮时登录屏幕上的一些代码:

@IBAction func logInTapped(_ sender: Any) 
    let email = firstNameTF.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    let password = lastNameTF.text!.trimmingCharacters(in: .whitespacesAndNewlines)

    
    Auth.auth().signIn(withEmail: email, password: password)  (result, error) in
        if error != nil
            //couldnt sign in
            self.errorLabel.text = error!.localizedDescription
            self.errorLabel.alpha = 1
         else 
            if #available(ios 13.0, *) 
                self.errorLabel.text = "Logged in"
                self.errorLabel.isHidden = false
                print("log in successful")
                self.userDefaults.setValue(true, forKey: "user_uid_key")
                self.userDefaults.synchronize()
                self.transitionToHome()

             else 
            
        
    
           

最后,这是我的 AppDelegate 中的代码:

var window: UIWindow?
let userDefaults = UserDefaults.standard

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 


    
    FirebaseApp.configure()
        check()
    window = UIWindow()
    window?.makeKeyAndVisible()

// window?.rootViewController = UINavigationController(rootViewController: SViewController())

    return true

    func check() 
        if userDefaults.value(forKey: "user_uid_key") as? Bool == true 

            
            self.window = UIWindow(frame: UIScreen.main.bounds)

调试项目的 zip 文件链接:https://drive.google.com/file/d/1Hd-E4yaHN70nH2wj0l9rP6xDLUC9oHEA/view?usp=sharing

新 SceneDelgate:

 func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) 
    
    guard let windowScene = (scene as? UIWindowScene) else  return 
    
    if userDefaults.value(forKey: "user_uid_key") as? Bool == true 
        print("userdefaults function is running")
        

        self.window = UIWindow(windowScene: windowScene)
  //                        self.window = UIWindow(windowScene: UIScreen.main.bounds)

        let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
        
        let initialViewController = storyboard.instantiateViewController(withIdentifier: "TBCID") as! UITabBarController

        self.window?.rootViewController = initialViewController

        self.window?.makeKeyAndVisible()


    

【问题讨论】:

【参考方案1】:

这里的问题是 UIWindow(frame:) 没有按预期工作,从 iOS 13 开始,您应该将您的逻辑移动到 SceneDelegate.swiftUIWindow(windowScene:)。另请查看缩进和右括号。

旧答案:

假设check() 中的第一个if 计算结果为true,您正在执行self.window?.rootViewController = initialViewControllerself.window?.makeKeyAndVisible(),但是当check() 完成时,您正在创建一个新的UIWindow 并在这个新的上执行window?.makeKeyAndVisible() UIWindow.

我认为你想要做的是(试图保持你的风格):

var window: UIWindow?
let userDefaults = UserDefaults.standard

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 

    FirebaseApp.configure()
        
    check()

    return true


func check() -> Bool 
    if userDefaults.value(forKey: "user_uid_key") as? Bool == true 
   
        self.window = UIWindow(frame: UIScreen.main.bounds)

        let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
            
        let initialViewController = storyboard.instantiateViewController(withIdentifier: "TBCID") as! TBCVC

        self.window?.rootViewController = initialViewController

        self.window?.makeKeyAndVisible()

     else 

        window = UIWindow()

        window?.rootViewController = UINavigationController(rootViewController: SViewController())

        window?.makeKeyAndVisible()
    

【讨论】:

感谢您的快速回复。我尝试了您的建议,但应用程序仍然无法保持登录状态。是否有可能因为我正在实例化的视图控制器 TBCVC 是标签栏控制器而不是普通视图控制器,所以代码执行不一样?这是我唯一能想到的其他事情。 check() 运行时,您确定userDefaults.value(forKey: "user_uid_key") as? Booltrue 我刚刚使用打印语句确认userDefaults.value(forKey: "user_uid_key") as? Boolcheck() 运行时为真。我不确定它可能是什么。 我仍然坚持这一点 你能创建一个测试项目来重现这个吗?我无法用你提供的信息来考虑其他任何事情@MichaelStangas

以上是关于UserDefaults 自动登录问题的主要内容,如果未能解决你的问题,请参考以下文章

swift中的自动登录功能

Swift 3 - UserDefaults 无缘无故自动清除

注销按钮操作不起作用

如何使用 UserDefaults 保存已登录状态?

如何在 swift 中使用 UserDefaults 实现登录/注销导航?

swift UserDefaults 中缺少登录凭据