0

在我的应用程序中,我使用 UserDefaults 来存储用户的登录状态(无论他们是否登录)和他们的用户名。它工作正常,当我登录时,关闭应用程序,然后再次打开它,我的应用程序跳过登录页面并识别出我已经登录。虽然,我现在正在尝试将注销按钮安装到单独的 viewController。单击时,此注销按钮需要 1.) 将 UserDefaults.loginStatus 重置为“False” 2.) 将 UserDefaults.username 重置为 nil 3.) 对登录页面执行 segue。

这是我的 ViewController.swift 文件中的相关代码。这是第一个控制 loginPage 的 viewController。

import UIKit
import Firebase

let defaults = UserDefaults.standard

class ViewController: UIViewController {
func DoLogin(username: String, password: String) {
    //I Am not including a lot of the other stuff that takes place in this function, only the part that involves the defaults global variable
    defaults.setValue(username, forKey: "username")
    defaults.setValue("true", forKey: "loginStatus")
    defaults.synchronize()
    self.performSegue(withIdentifier: "loginToMain", sender: self) //This takes them to the main page of the app
}

override func viewDidLoad() {
    super.viewDidLoad()
    if let stringOne = defaults.string(forKey: "loginStatus") {
        if stringOne == "true" { //If the user is logged in, proceed to main screen
            DispatchQueue.main.async
                {
                    self.performSegue(withIdentifier: "loginToMain", sender: self)
            }
        }
    }

}

下面是我在 SecondViewController.swift 中的代码,尤其是注销功能。

import UIKit
import Firebase

class SecondViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
     if let username = defaults.string(forKey: "username") {
            checkAppSetup(username: username) //This is an unrelated function
            //I included this because this works fine. Proving that I am able to read the defaults variable fine from this other viewController
      }
}
@IBAction func logout(_ sender: Any) {
        defaults.setValue("false", forKey: "username")
        defaults.setValue("false", forKey: "loginStatus")
        defaults.synchronize()

        performSegue(withIdentifier: "logoutSegue", sender: nil)
    }

运行注销功能时,segue 执行良好,但默认值不会更改。有人可以解释为什么以及我能做些什么来解决这个问题吗?

**旁注,我实际上不会将默认值设置为“false”和“false”。在我调试此问题时,这只是暂时的。

4

2 回答 2

3

几件事。

您应该使用set(_:forKey:)and object(_:forKey) 来读取键/值对并将其写入默认值,而不是setValue(_:forKey). (但是,您的使用defaults.string(forKey: "loginStatus")是正确的。)

您可能应该将 nil 写入 userName 键:

defaults.set(nil, forKey: "username")

而且您的注销IBAction几乎肯定应该设置loginStatusfalse,而不是true

尝试改变这些东西。

此外,除非您在 Xcode 中终止您的应用程序,而不是按下设备/模拟器上的主页按钮以使其正常退出,否则没有理由调用同步。

于 2017-03-05T16:52:20.113 回答
2

嘿,我最近使用了完全相同的概念:

1)在您的初始视图中viewDidLoad(),检查是否有人已经登录,并且一次只能一个用户登录一台设备,因此我们检查如下

let defaults = UserDefaults.standard
if defaults.object(forKey: "userName") != nil && defaults.object(forKey: "userPassword") != nil
   {
          let loginObject = self.storyboard?.instantiateViewController(withIdentifier: "YourSecondViewController") as! YourSecondViewController
//As someone's details are already saved so we auto-login and move to second view    
}}

2)在您的登录按钮功能中,检查您要检查的任何条件,然后在相同的情况下,如果条件满足,则将数据保存到 userDefaults。

// If no details are saved in defaults, then control will come to this part, where we will save the entered userName and Password

    let defaults = UserDefaults.standard
    defaults.set(self.enteredUseName, forKey: "userName")
    defaults.set(self.enteredPassword, forKey: "Password")
    defaults.synchronize()

3)在注销按钮上,删除userDefaults并再次加载登录视图:

let defaults = UserDefaults.standard
defaults.removeObject(forKey: "userName") //We Will delete the userDefaults
defaults.removeObject(forKey: "userPassword")
defaults.synchronize() //Sync. the defaults.
navigationController?.popToRootViewController(animated: true) //Move Back to initial view.

4)如果您使用的是导航控件,则必须使用 :P 那么您肯定会看到返回按钮,如果单击该按钮将打开第二个视图,因为您可以在viewDidLoad()登录视图中隐藏导航栏

  self.navigationController?.navigationBar.isHidden = true
于 2017-03-05T18:43:26.707 回答