在其他视图控制器中访问Swift中的UserDefaults
在我的应用程序中,我使用UserDefaults来存储用户的登录状态(不管他们是否已登录)以及他们的用户名。它工作正常,当我登录时,关闭应用程序,并再次打开我的应用程序跳过登录页面,并认识到我已经登录。虽然,我现在试图安装一个注销按钮到一个单独的viewController。单击时,此注销按钮需要1.)将UserDefaults.loginStatus重置为“False”2.)将UserDefaults.username重置为零3.)对登录页面执行segue。在其他视图控制器中访问Swift中的UserDefaults
以下是我的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”。这只是暂时的,因为我正在调试这个问题。
几件事。
您应该使用set(_:forKey:)
和object(_:forKey
)将键/值对读取和写入默认值,而不是setValue(_:forKey)
。 (您使用的defaults.string(forKey: "loginStatus")
是正确的,但是。)
或许你也应该写一个零到用户名输入键:
defaults.set(nil, forKey: "username")
和你注销IBAction
应该几乎可以肯定是设置loginStatus
到false
,不true
。
尝试改变这些东西。
此外,没有理由调用同步,除非您在Xcode中终止您的应用程序,而不是按设备/模拟器上的主页按钮以使其正常退出。
完美的工作!如果你不介意解释,.set和.setValue之间的区别究竟是什么?而且,什么是.synchronize呢? –
'setValue:forKey:'函数是一个KVC(键值编码)方法,它可以在任何NSObject上设置它的值。我不认为它与'UserDefaults'正常工作。 '.synchronize'函数强制'UserDefaults'立即写入磁盘。这是相对昂贵的,所以如果您的应用可能会在它有机会将更改保存到默认值之前终止,则应该只使用它(例如,如果您在Xcode中按命令周期以在开发期间杀死应用程序,或者如果您使用force-quit从跳板。) –
了解。感谢伟大的回答和优秀的解释! –
嘿我最近使用完全相同的概念:
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
这里'defaults.setValue(“真”,forKey:“登录状态“)'你正在设置'true'。这是对的吗?为了调试目的?我猜它应该是'false' –
是的,这是我提出这个问题时的一个错误。在真实的代码中它确实会说“错误”。谢谢。但无论哪种方式,无论我在SecondViewController中设置它,在ViewController.swift –
中访问它时都不会出现。您可以在此行上设置断点“performSegue(withIdentifier:”logoutSegue“,sender:nil)'并在控制台中输入:'po UserDefaults.standard.value(forKey:“loginStatus”)'看看它会返回“true”还是“false”? –