How to do signin / signup and logout navigation using userdefaults in swift?

1k Views Asked by At

i have scenedelegate, appdelegate, signinVC, signupVC, and homeVC

viewcontroller flow like below

      UINavigationController(initialVC) ->SigninVC (signin and signup buttons) -> homeVC(logoutBtn)

i need when i signIn or signUp i need to move homeVC and if i logout i need back to loginVC and i need user auto login until i hit logout button in homeVC

in signupVC:

  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)
        
    }
}

in 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)
}
}

in 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)
}
}

with the above code only recent registered user able to login and auto login not working

how to login all registered users and how to auto login to home page until i hit logout button.. please do help with code

2

There are 2 best solutions below

10
On BEST ANSWER

In signinVC add the following line in 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)
            }
        }

Modify signupVC like following

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
}

Finally modify loginBtnClicked method as following

@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")
    }
    
}
0
On

I would definitely recommend you read some articles about either MVC or MVVM architectures :) (https://marcosantadev.com/mvvmc-with-swift/) <- Example.

I understand that maybe you are just expecting an answer for your question so the most simple one is (And not the correct approach!!):

You can just save a bool param to userDefaults which will indicate if the user is logged in or not. ()

Once you start your app you can check if the param exists in UserDefaults and depending on that you navigate the user to your desired controller.

Also you can add an observer if the value in UserDefaults changes, and according the change again you can navigate the user away.

As I mentioned you before, I am not sure what are you creating (if it's some kind of app or just training) but definitely read some articles about architectures and try to use one :) Good luck in your path of learning iOS development.