Ios 从其他ViewController访问Swift中的用户默认值
在我的应用程序中,我使用UserDefaults存储用户的登录状态(无论他们是否登录)及其用户名。它的工作原理很好,当我登录时,关闭应用程序,然后再次打开它。我的应用程序跳过登录页面,并识别我已经登录。不过,我现在正在尝试将注销按钮安装到单独的viewController。单击时,此注销按钮需要1.)将UserDefaults.loginStatus重置为“False”2.)将UserDefaults.username重置为nil 3.)执行登录页面的切换 以下是我的ViewController.swift文件中的相关代码。这是第一个控制登录页面的viewControllerIos 从其他ViewController访问Swift中的用户默认值,ios,swift,uiviewcontroller,nsuserdefaults,userdefaults,Ios,Swift,Uiviewcontroller,Nsuserdefaults,Userdefaults,在我的应用程序中,我使用UserDefaults存储用户的登录状态(无论他们是否登录)及其用户名。它的工作原理很好,当我登录时,关闭应用程序,然后再次打开它。我的应用程序跳过登录页面,并识别我已经登录。不过,我现在正在尝试将注销按钮安装到单独的viewController。单击时,此注销按钮需要1.)将UserDefaults.loginStatus重置为“False”2.)将UserDefaults.username重置为nil 3.)执行登录页面的切换 以下是我的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(\uquo:forKey:)
和object(\uquo:forKey
)来读取和写入默认的键/值对,而不是setValue(\uquo:forKey)
。(但是,您使用的defaults.string(forKey:“loginStatus”)
是正确的。)
您可能应该将nil写入用户名密钥:
defaults.set(nil, forKey: "username")
您的注销iAction
几乎肯定应该将loginStatus
设置为false
,而不是true
试着改变这些事情
此外,没有理由调用synchronize,除非您在Xcode中终止应用程序,而不是按下设备/模拟器上的home(主页)按钮以使其正常退出。有几件事
您应该使用set(\uquo:forKey:)
和object(\uquo:forKey
)来读取和写入默认的键/值对,而不是setValue(\uquo:forKey)
。(但是,您使用的defaults.string(forKey:“loginStatus”)
是正确的。)
您可能应该将nil写入用户名密钥:
defaults.set(nil, forKey: "username")
您的注销iAction
几乎肯定应该将loginStatus
设置为false
,而不是true
试着改变这些事情
此外,没有理由调用synchronize,除非您在Xcode中终止应用程序,而不是按下设备/模拟器上的home(主页)按钮以使其正常退出。嘿,我最近使用了完全相同的概念: 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
嘿,我最近使用了完全相同的概念: 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(“true”,forKey:“loginStatus”)
您正在设置true
。对吗?为了调试的目的?我想应该是false
是的,这是我问这个问题时的一个打字错误。在真正的代码中,它确实会说“false”。非常感谢。但是无论哪种方式,当我在ViewController中访问它时,在SecondViewController中设置它的任何内容都不会出现。Swift您可以在这一行performsgue(带有标识符:“logoutSegue”,发件人:nil)
上设置断点,然后在控制台中键入:po UserDefaults.standard.value(forKey:“loginStatus”)
并查看它将返回什么true
或false
?我相信Duncan C回答了我下面的问题,我只需要使用.set(u,forKey:“”)而不是.setValue。但是谢谢你的主意!这里是defaults.setValue(“true”,forKey:“loginStatus”)
您正在设置true
。对吗?为了调试的目的?我想应该是false
是的,这是我问这个问题时的一个打字错误。在真正的代码中,它确实会说“false”。非常感谢。但是无论哪种方式,当我在ViewController中访问它时,在SecondViewController中设置它的任何内容都不会出现。Swift您可以在这一行performsgue(带有标识符:“logoutSegue”,发件人:nil)
上设置断点,然后在控制台中键入:po UserDefaults.standard.value(forKey:“loginStatus”)
并查看它将返回什么true
或false
?我相信Duncan C回答了我下面的问题,我只需要使用.set(u,forKey:“”)而不是.setValue。但是谢谢你的主意!那很有效!如果您不介意解释的话,.set和.setValue之间到底有什么区别?此外,.synchronize究竟是做什么的呢?setValue:forKey:
函数是一种KVC(键值编码)方法,适用于任何NSOb