Freddy Benson
Freddy Benson

Reputation: 775

Can I retrieve data from NSUserDefaults after app termination?

I was wondering where NSUserDefaults is writing all the stored data to: to the app memory or to the device the app is running on? In the latter case, I guess I should be able to retrieve stored data from NSUserDefaults even if the app has been completely shut down, right? Basically what I'm trying to do: at runtime I want to check whether or not the user was logged in when he/she shut down the app (which I store in NSUserDefaults as a Boolean at the moment a user logs in or logs out), and if the user was logged in, I want to set a different root view controller from the original root view controller a user would see if the app was opened for the first time. I've tried a lot of different things, but nothing seems to work when I test it on my device. Is NSUserDefaults the best approach to do this (if so, then how?) or are there better alternatives to do this?

Upvotes: 0

Views: 862

Answers (2)

MwcsMac
MwcsMac

Reputation: 7168

When using 'NSUserDefaults' for something simple like this it will work well for what you are trying to achieve.

This is the code you would place in your AppDelegate that will handle sending the user to the correct view based on the value.

Swift 2

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {


    let logonStatus = NSUserDefaults.boolForKey("LogonStatus")

    if logonStatus  {
        print("User logged in.")

        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let initialViewController = storyboard.instantiateViewControllerWithIdentifier("navController") as! UINavigationController

        self.window?.rootViewController = initialViewController
        self.window?.makeKeyAndVisible()

    } else {
        print("User not Logged in.")

        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let initialViewController = storyboard.instantiateViewControllerWithIdentifier("loginViewController") as UIViewController

        self.window?.rootViewController = initialViewController
        self.window?.makeKeyAndVisible()

    }

    return true
}

Then in your logout or logon viewController or the code to perform the logout or logon you would just need to make sure to set the 'NSUsersDefaults' value.

NSUserDefaults.setBool(true, forKey: "logonStatus") // Logged On
NSUserDefaults.setBool(false, forKey: "logonStatus") // Logged Off

Swift 3

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {


    let logonStatus = UserDefaults.standard.bool(forKey: "LogonStatus")

    if logonStatus  {
        print("User logged in.")

        self.window = UIWindow(frame: UIScreen.main.bounds)

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let initialViewController = storyboard.instantiateViewController(withIdentifier: "navController") as! UINavigationController

        self.window?.rootViewController = initialViewController
        self.window?.makeKeyAndVisible()

    } else {
        print("User not Logged in.")

        self.window = UIWindow(frame: UIScreen.main.bounds)

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let initialViewController = storyboard.instantiateViewController(withIdentifier: "loginViewController") as UIViewController

        self.window?.rootViewController = initialViewController
        self.window?.makeKeyAndVisible()

    }

    return true
}

Set 'UserDefaults'

UserDefaults.standard.set(true, forKey: "LogonStatus")

Upvotes: 1

Dylan Gattey
Dylan Gattey

Reputation: 1724

You've got a few questions here. NSUserDefaults is persistent across app launches, per this other answer on StackOverflow: Data persistence through NSUserDefaults. However, once you delete the app, you will lose the data.

In terms of programming for a root view controller, I would say yeah, if you want to show the login root view controller, that's a pretty strong case for storing login persistence in NSUserDefaults. Just don't store their login directly in the defaults of course :)

One thing I would note is that it quickly gets hard to reason about view hierarchy and you can introduce pretty nasty bugs if the root view controller is changing. Like, once the user logs in, what do you do with the old root view controller? Instead of what you describe, I'd keep the same root view controller, but present a modal for login over the top of the root if a login is needed. Simpler logic and your app will be more stable.

Upvotes: 1

Related Questions