-2

I have a login screen LoginViewController and homescreen HomeScreenController which is pushed when the user is successfully logged in). I have declared a variable for UserDefaults as below in a seperate class:

class User {
    static var isLoggedIn = UserDefaults.standard.bool(forKey:"islogged")
}

When the user clicks login Button, the code is as below

ButtonAction:
{
    User.isLoggedin = true
    //Performsegue........to homescreen
}

ViewDidload {

    if user.isloggedin == true {
        //Performsegue......homescreen
    }
    else {
        Show some alerts
    }
}

Here in my case...nothing happens...sorry for the rough code since I am using my smartphone to ask this question.

Am I missing something in appdelegate or somewhere else. I just want to use the variables as it is because I don't want to change the entire code in my project. The project is actually complicated and I just made an example to make you guys understand my situation. This is not the exact code.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Jaseel.Dev
  • 730
  • 1
  • 7
  • 19

7 Answers7

2

Using a class with a static variable for a UserDefaults value is bad practice. Apart from that setting the static variable doesn't update the value in UserDefaults.

In the button action set the value in UserDefaults and perform the segue

@IBAction func login(_ sender : Any)  {
    UserDefaults.standard.set(true, forKey:"islogged")
    performSegue(...
}

In viewDidLoad get the value directly from UserDefaults

func viewDidLoad() {
    super.viewDidLoad()
    if UserDefaults.standard.bool(forKey:"islogged") {
        performSegue(...
    } else {
        // present error
    }

}
vadian
  • 274,689
  • 30
  • 353
  • 361
0

I think this is happening coz you are calling the UserDefaults within the User class. This does not get executed until the class is initialized.

Try to do this directly in viewDidLoad(), it should work.

if UserDefaults.standard.bool(forKey:"islogged") {
    Performsegue......homescreen
}else{
    Show some alerts
}
Cedan Misquith
  • 1,134
  • 9
  • 20
  • Yess but the point i was trying to make was that you should not use a UserDefault within a static variable class. It not good practice. You can also do what vadian has suggested. Thats the best approach. – Cedan Misquith May 30 '19 at 08:39
0

Try this instead of your isLoggedIn line of code

static var isLoggedIn: Bool {
    get {
        return UserDefaults.standard.bool(forKey: "isLoggedIn")
    }
    set {
        UserDefaults.standard.setValue(newValue, forKey: "isLoggedIn")
        UserDefaults.standard.synchronize()
    }
}
  • 2
    Don't use `setValue(` in `UserDefaults` unless you can explain why KVC is needed. And don't use `synchronize()`. – vadian May 30 '19 at 08:37
  • I've been storing project preferences this way for a while now. I'm not really sure about what you mean but I'm going to do some research. Thanks for your comment. –  May 30 '19 at 08:44
0

I think you're probably trying to achieve this:

class User {
    static var isLoggedIn: Bool {
        get {
            return UserDefaults.standard.bool(forKey: "islogged")
        }
        set(aIsLoggedIn) {
            UserDefaults.standard.set(aIsLoggedIn, forKey: "islogged")
        }
    }
}

The problem with your code is that you don't save the state of isLoggedIn, so at every startup the value is always false

Marco
  • 1,572
  • 1
  • 10
  • 21
0

I believe you have a problem with the call to performSegue:. You cannot call this method on viewDidLoad because the viewcontroller is not yet fully setup. Try moving your viewDidLoad to viewDidAppear

Move viewDidLoad code to viewDidAppear

override func viewDidAppear(animated: Bool){
    super.viewDidAppear(animated)
    if User.isLoggedIn{
        performSegue("someIdentifier")
    }else{
       //show some alerts. 
    }

}


Also, use a computed var for your isLoggedIn. taken from Marco:


  static var isLoggedIn: Bool {
        get {
            return UserDefaults.standard.bool(forKey: "islogged")
        }
        set(aIsLoggedIn) {
            UserDefaults.standard.set(aIsLoggedIn, forKey: "islogged")
        }
    }

Perform Segue on ViewDidLoad

  • I roughly wrote those methods...i only want to mention userdefaults problem...even if i use print...it doesnt show success..so pls – Jaseel.Dev May 30 '19 at 08:50
0

In your code

class User {    
    static var isLoggedIn = UserDefaults.standard.bool(forKey:"islogged")    
}

The 'isLoggedIn' is just a value type. It will not change by UserDefaults.standard's some value's changing. Because your declare is just set a default value to that.if you want to have a variable to imply the global unique semantic, you must insure that modify it in the same address, and get it from the same address too.

0

I think you need to hide login vc if user was logined, right?
Do it in HomeVC

@IBAction func login(_ sender : Any)  {
   if login == true{
      UserDefaults.standart.set("true", forKey:"islogged")
    }
}   

And paste it to AppDelegate

var window: UIWindow?


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    self.window = UIWindow(frame: UIScreen.main.bounds)
    let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    var initialViewController: UIViewController

    if UserDefaults.standard.string(forKey: "islogged") == "true"//your condition if user is already logged in or not
    {
        // if already logged in then redirect to MainViewController

        initialViewController = mainStoryboard.instantiateViewController(withIdentifier: "HomeVC") as! UITabBarController // 'MainController' is the storyboard id of HomeViewController
    }
    else
    {
        //If not logged in then show LoginViewController
        initialViewController = mainStoryboard.instantiateViewController(withIdentifier: "LoginVC") as! SignInViewController // 'LoginController' is the storyboard id of LoginViewController

    }

    self.window?.rootViewController = initialViewController

    self.window?.makeKeyAndVisible()

    return true
}
Marshall
  • 141
  • 3
  • 9