swift - 如何在 swift 中使用 userdefaults 进行登录/注册和注销导航?
问题描述
我有 scenedelegate、appdelegate、signinVC、signupVC 和 homeVC
视图控制器流程如下
UINavigationController(initialVC) ->SigninVC (signin and signup buttons) -> homeVC(logoutBtn)
我需要当我登录或注册时我需要移动 homeVC,如果我注销我需要回到 loginVC,我需要用户自动登录,直到我点击 homeVC 中的注销按钮
在注册VC中:
class RegisterViewController: UIViewController {
@IBOutlet weak var firstNameTextfield: UITextField!
@IBOutlet weak var lastNameTextfield: UITextField!
@IBOutlet weak var emailTextfield: UITextField!
@IBOutlet weak var passwordTextfield: UITextField!
@IBAction func registerBtnClicked(_ sender: Any) {
if firstNameTextfield.text?.isEmpty == true{
self.showAlert(title: "Registration", message: "please enter first name")
}
else if lastNameTextfield.text?.isEmpty == true{
self.showAlert(title: "Registration", message: "please enter last name")
}else if emailTextfield.text?.isEmpty == true{
self.showAlert(title: "Registration", message: "please enter email")
}else if passwordTextfield.text?.isEmpty == true{
self.showAlert(title: "Registration", message: "please enter password")
}
else{
UserDefaults.standard.set(firstNameTextfield.text, forKey: "userName")
UserDefaults.standard.set(lastNameTextfield.text, forKey: "lastName")
UserDefaults.standard.set(emailTextfield.text, forKey: "email")
UserDefaults.standard.set(passwordTextfield.text, forKey: "userPassword")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
navigationController?.pushViewController(vc, animated: true)
}
}
在signinVC中:
class ViewController: UIViewController {
@IBOutlet weak var userNameTextfield: UITextField!
@IBOutlet weak var passwordTextfield: UITextField!
@IBAction func loginBtnClicked(_ sender: Any) {
let uName = UserDefaults.standard.string(forKey: "userName")
let uPassword = UserDefaults.standard.string(forKey: "userPassword")
if userNameTextfield.text == uName && passwordTextfield.text == uPassword{
UserDefaults.standard.set(true, forKey: "USER_LOGIN")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
navigationController?.pushViewController(vc, animated: true)
}
else{
showAlert(title: "LogIn", message: "please enter username and password")
}
}
@IBAction func registerBtnClicked(_ sender: Any) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RegisterViewController") as! RegisterViewController
navigationController?.pushViewController(vc, animated: true)
}
}
在 homeVC 中:
class HomeViewController: UIViewController {
@IBAction func logoutBtnClicked(_ sender: Any) {
UserDefaults.standard.set(false, forKey: "USER_LOGIN") //logging session off
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
navigationController?.pushViewController(vc, animated: true)
}
}
使用上面的代码只有最近注册的用户才能登录并且自动登录不起作用
如何登录所有注册用户以及如何自动登录到主页,直到我点击注销按钮..请提供代码帮助
解决方案
在 signinVC 中在 viewDidLoad 中添加以下行
if UserDefaults.standard.bool(forKey: "USER_LOGIN"){
//navigate to home page
DispatchQueue.main.async {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
navigationController?.pushViewController(vc, animated: true)
}
}
修改signupVC如下
class RegisterViewController: UIViewController {
@IBOutlet weak var firstNameTextfield: UITextField!
@IBOutlet weak var lastNameTextfield: UITextField!
@IBOutlet weak var emailTextfield: UITextField!
@IBOutlet weak var passwordTextfield: UITextField!
var userDict : Dictionary<String,UserData>?
@IBAction func registerBtnClicked(_ sender: Any) {
if firstNameTextfield.text?.isEmpty == true{
self.showAlert(title: "Registration", message: "please enter first name")
}
else if lastNameTextfield.text?.isEmpty == true{
self.showAlert(title: "Registration", message: "please enter last name")
}else if emailTextfield.text?.isEmpty == true{
self.showAlert(title: "Registration", message: "please enter email")
}else if passwordTextfield.text?.isEmpty == true{
self.showAlert(title: "Registration", message: "please enter password")
}
else{
self.userDict = UserDefaults.standard.dictionary(forKey: "UserList") as! Dictionary<String, RegisterViewController.UserData>
let userData = UserData(userName: firstNameTextfield.text, lastName: lastNameTextfield.text, email: emailTextfield.text, userPassword: passwordTextfield.text)
self.userDict[firstNameTextfield.text] = userData
UserDefaults.standard.setValue(self.userDict, forKey: "UserList")
DispatchQueue.main.async {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
navigationController?.pushViewController(vc, animated: true)
}
}
}
struct UserData {
var userName : String
var lastName : String
var email : String
var userPassword : String
}
最后修改 loginBtnClicked 方法如下
@IBAction func loginBtnClicked(_ sender: Any) {
let userDict = UserDefaults.standard.dictionary(forKey: "UserList") as! Dictionary<String, UserData>
guard let usrData = userDict[userNameTextfield.text] as! UserData else {
// no user registered with this user name
return
}
if usrData.userPassword == passwordTextfield.text {
// login successfull
UserDefaults.standard.set(true, forKey: "USER_LOGIN")
DispatchQueue.main.async {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
navigationController?.pushViewController(vc, animated: true)
}
}else{
//login failed
showAlert(title: "LogIn", message: "please enter username and password")
}
}
推荐阅读
- r - 如何在 R 中编写一个函数来下载文件并收集数据?
- node.js - azure 聊天机器人 [SDK4] 消息状态显示“无法发送,重试”,同时在直线频道上进行实时(人工)代理聊天
- json - 编码::UndefinedConversionError 转储到 json
- android - Android 模拟器问题 - Google 帐户对话框被挤到顶部
- c++ - 构建一个基于链表的堆栈,可以包含原始数据类型和用户定义的数据类型
- ubuntu - 自动化 rsync 密码输入的最佳方法是什么?
- php - Silverstripe ModelAdmin 拖放 可排序
- reactjs - React Native - 使用 react-navigation 和 react-redux 在屏幕之间切换时数据丢失
- javascript - 有没有办法在使用条件渲染时保持 ScrollView 在 react-native 中的位置?
- rust - 重构匹配语句以满足借用检查器