从其他视图控制器访问 Swift 中的 UserDefaults
Accessing UserDefaults in Swift from other viewControllers
在我的应用程序中,我使用 UserDefaults 来存储用户的登录状态(无论他们是否登录)和他们的用户名。它工作正常,因为当我登录、关闭应用程序并再次打开它时,我的应用程序会跳过登录页面并识别出我已经登录。虽然,我现在正在尝试将注销按钮安装到单独的 viewController.单击后,此注销按钮需要 1.) 将 UserDefaults.loginStatus 重置为 "False" 2.) 将 UserDefaults.username 重置为 nil 3.) 对登录页面执行 segue。
这是我的 ViewController.swift 文件中的相关代码。这是控制登录页面的第一个 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"。在我调试此问题时,这只是暂时的。
几件事。
您应该使用 set(_:forKey:)
和 object(_:forKey
) 将 key/value 对读写为默认值,而不是 setValue(_:forKey)
。 (但是,您对 defaults.string(forKey: "loginStatus")
的使用是正确的。)
您可能应该将 nil 写入 userName 键:
defaults.set(nil, forKey: "username")
并且您的注销 IBAction
应该几乎肯定会将 loginStatus
设置为 false
,而不是 true
。
尝试改变这些东西。
此外,没有理由调用同步,除非您在 Xcode 中终止您的应用程序,而不是按 device/simulator 上的主页按钮以让它正常退出。
嘿,我最近使用了完全相同的概念:
1) 在你的初始视图中,在 viewDidLoad()
中,检查是否有人已经登录,并且一次只能一个用户登录一个设备,所以我们检查 like
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
在我的应用程序中,我使用 UserDefaults 来存储用户的登录状态(无论他们是否登录)和他们的用户名。它工作正常,因为当我登录、关闭应用程序并再次打开它时,我的应用程序会跳过登录页面并识别出我已经登录。虽然,我现在正在尝试将注销按钮安装到单独的 viewController.单击后,此注销按钮需要 1.) 将 UserDefaults.loginStatus 重置为 "False" 2.) 将 UserDefaults.username 重置为 nil 3.) 对登录页面执行 segue。
这是我的 ViewController.swift 文件中的相关代码。这是控制登录页面的第一个 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"。在我调试此问题时,这只是暂时的。
几件事。
您应该使用 set(_:forKey:)
和 object(_:forKey
) 将 key/value 对读写为默认值,而不是 setValue(_:forKey)
。 (但是,您对 defaults.string(forKey: "loginStatus")
的使用是正确的。)
您可能应该将 nil 写入 userName 键:
defaults.set(nil, forKey: "username")
并且您的注销 IBAction
应该几乎肯定会将 loginStatus
设置为 false
,而不是 true
。
尝试改变这些东西。
此外,没有理由调用同步,除非您在 Xcode 中终止您的应用程序,而不是按 device/simulator 上的主页按钮以让它正常退出。
嘿,我最近使用了完全相同的概念:
1) 在你的初始视图中,在 viewDidLoad()
中,检查是否有人已经登录,并且一次只能一个用户登录一个设备,所以我们检查 like
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