问题描述
您好,我制作了包含登录和注册功能的应用程序,该功能运行良好,但是关闭应用程序时无法保持用户登录状态;它将用户返回到主视图控制器,在该视图控制器中,用户将不得不在注册或登录之间进行选择。
任何人都可以帮忙吗?
AppDelegate:
import UIKit
import Firebase
@UIApplicationMain
class AppDelegate: UIResponder,UIApplicationDelegate {
func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
sleep(2);
FirebaseApp.configure()
return true
}
}
登录:
import UIKit
import Firebase
class LoginController: UIViewController {
// MARK: - Properties
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var login: UIButton!
@IBOutlet weak var emailTextField: UILabel!
var email = String()
// MARK: - Init
override func viewDidLoad() {
super.viewDidLoad()
emailTextField.text = email
}
// MARK: - Selectors
@IBAction func loginButton(_ sender: UIButton) {
guard let password = passwordTextField.text else {return}
let finalPassword = password.trimmingCharacters(in: .whitespacesAndNewlines)
//Password Validation and Alert
if Utilities.isPasswordValid(finalPassword) == true {
print("Password is Valid")
} else {
print("Password is not Valid")
let myAlert = UIAlertController(title:"",message:"Please make sure your password is at least six characters,includes at least one number or special character,and is not a commonly used password.",preferredStyle:UIAlertController.Style.actionSheet)
let okAction = UIAlertAction(title: "Cancel",style: UIAlertAction.Style.destructive,handler: nil)
myAlert.addAction(okAction)
self.present(myAlert,animated: true,completion: nil)
return
}
loginUserIn(withEmail: email,password: password)
}
// MARK: - API
func loginUserIn(withEmail email:String,password: String) {
Auth.auth().signIn(withEmail: email,password: password) { (result,error) in
if let error = error {
print("Failed to sign in",error.localizedDescription)
return
}
print("Success Log In")
UserDefaults.standard.set(true,forKey: "nil")
UserDefaults.standard.synchronize()
}
}
}
注册:
import UIKit
import Firebase
class SignUpController: UIViewController {
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var signUp: UIButton!
@IBOutlet weak var emailText: UILabel!
var email = String()
// MARK: - Init
override func viewDidLoad() {
super.viewDidLoad()
emailText.text = email
signUp.addTarget(self,action: #selector(signUpButton),for: .touchUpInside)
}
// MARK: - Selectors
@IBAction func signUpButton(_ sender: Any) {
guard let password = passwordTextField.text,// use Swift's ability to infer the type here (and a couple other places)
case let finalPassword = password.trimmingCharacters(in: .whitespacesAndNewlines),Utilities.isPasswordValid(finalPassword) else {
// If we get here then either the password is null
// or the password is not valid
print("Password is not valid")
// we need to display the alert,I'll move that into another function
showPasswordInvaliDalert()
return
}
// If we get here the password is valid
print("Password is valid:",finalPassword)
createuser(withEmail: email,password: password)
}
func showPasswordInvaliDalert() {
// this is an alert not an action sheet
let alert = UIAlertController(title: "",message: "Please make sure your password is at least six characters,preferredStyle: .actionSheet)
// this is not a destructive action
let okAction = UIAlertAction(title: "Cancel",style: .destructive,handler: nil)
alert.addAction(okAction)
self.present(alert,completion: nil)
}
// MARK: - API
func createuser(withEmail email:String,password: String) {
Auth.auth().createuser(withEmail: email,error) in
if let error = error {
print("Failed to sign up",error.localizedDescription)
return
}
guard let uid = result?.user.uid else {return}
let values = ["email": email]
Database.database().reference().child("users").child(uid).updateChildValues(values,withCompletionBlock: { (error,ref) in
if let error = error {
print("Falied to update",error.localizedDescription)
return
}
let mainStoryBoard = UIStoryboard(name: "Main",bundle: Bundle.main)
guard let controller = mainStoryBoard.instantiateViewController(withIdentifier: "SubsViewController") as? SubsViewController else {
print("Error")
return
}
self.navigationController?.pushViewController(controller,animated: true)
// self.present(controller,completion: nil)
})
}
}
}
解决方法
遵循以下步骤:-
- 一次用户成功登录集
UserDefaults.standard.set(true,forKey: "islogin")
- 将以下代码添加到appdelegate
private func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let islogin = UserDefaults.standard.object(forKey: "token")
if islogin {
//set your login viewcontroller as root viewcontroller
}else{
//open the home screen
}
return true
}
- 不要忘记在注销时将userdefault设置为false。
-
设置布尔检查。
-
在登录时将其设置为true。
-
在注销时将其设置为false。
-
在sceneDelegate上检查其状态
-
根据当前值加载视图控制器。
让isLoggedIn = userdefaults.standard.bool(forKey:“ loggedInValue”)
if isLoggedIn == true{ print("loggedIn") }else{ print("loggedOut") }
在您的sceneDelegate集中设置
func scene(_ scene: UIScene,willConnectTo session: UISceneSession,options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard,the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
let window = UIWindow(windowScene: scene as! UIWindowScene)
// Assign window to SceneDelegate window property
self.window = window
if let loggedIn = UserDefaults.standard.bool(forKey: "IsUserLoggedIn") as? Bool{
if loggedIn{
let initialViewController = storyboard.instantiateViewController(withIdentifier: "LoggedInScreen")
self.window?.rootViewController = initialViewController
}else{
let initialViewController = storyboard.instantiateViewController(withIdentifier: "SignUpScreen")
self.window?.rootViewController = initialViewController
}
}else{
let initialViewController = storyboard.instantiateViewController(withIdentifier: "SignUpScreen")
self.window?.rootViewController = initialViewController
}
self.window?.makeKeyAndVisible()
guard let _ = (scene as? UIWindowScene) else { return }
}