Search code examples
swiftnsuserdefaults

How can I get an updated value from UserDefaults?


I have an Onboarding controller, when a user has completed Onboarding I am writing a value in UserDefaults and then dismissing the OnboardingViewController.

My base viewcontroller however is pushing them back to the Onboarding flow as UserDefaults.standard.bool(forKey: "ONBOARDING|COMPLETE") is returning false.

If I restart my app however is will return true and they are pushed to the correct VC.

My Base ViewController

class ViewController: UIViewController {

    var onboardingComplete: Bool {
        get {
            return UserDefaults.standard.bool(forKey: "ONBOARDING|COMPLETE")
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        print(UserDefaults.standard.bool(forKey: "ONBOARDING|COMPLETE"))
        print(onboardingComplete)

        setBaseViewController()
    }

    fileprivate func setBaseViewController() {
        if onboardingComplete {
            print("has completed onboarding")
        } else {
            let layout = UICollectionViewFlowLayout()
            navigationController?.present(OnboardingController(collectionViewLayout: layout), animated: true, completion: { })
        }
    }
}

My Onboarding controller has a method in which I am using to set the value as complete

  @objc func handleCompleteOnboarding() {

        dismiss(animated: true) {
            DispatchQueue.main.async {
                UserDefaults.standard.set(true, forKey: "ONBOARDING|COMPLETE")
            }
        }
    }

Solution

  • You are setting the value in the completion handler.

    Move this outside of dismiss.

    @objc func handleCompleteOnboarding() {
        UserDefaults.standard.set(true, forKey: "ONBOARDING|COMPLETE")
        dismiss(animated: true)
    }
    

    You have essentially created a race condition between you setting the value and your viewDidAppear method being called.