Search code examples
swiftuserdefaults

read a UserDefault value when the app starts


UserDefault doesn't work, when I change the color of the app, then I close it and reopen it I don't see the changes.

My intent is to create the preferences that the user sets on the app.

I also tried putting the code inside SceneDelegate.swift but it doesn't work there either.

UserDefaultManager

    import Foundation

class UserDefaultManager {

    static let sharedUserDefault = UserDefaultManager()
    
    var darkmode = Bool()
    
    let keyDarkmode = "UserDefaultDarkmode"

    let userDef = UserDefaults.standard
    
}

ViewController

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var theme: UISwitch!
    
    let shared = UserDefaultManager.sharedUserDefault
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // theme.isOn = false
        theme.setOn(false, animated: false)

        if shared.userDef.object(forKey: shared.keyDarkmode) != nil {
            
          shared.darkmode = shared.userDef.object(forKey: shared.keyDarkmode) as? Bool ?? Bool()
            
            if shared.darkmode == true {
                overrideUserInterfaceStyle = .dark
            } else {
                overrideUserInterfaceStyle = .light
            }
            
            shared.userDef.synchronize()
            
        }
        
    }

    
    @IBAction func themeSwitch(_ sender: UISwitch) {
        
        if sender .isOn {
            overrideUserInterfaceStyle = .dark
            shared.darkmode = true
            shared.userDef.set(shared.darkmode, forKey: shared.keyDarkmode)
            
            shared.userDef.synchronize()
        } else {
            overrideUserInterfaceStyle = .light
            shared.darkmode = false
            shared.userDef.set(shared.darkmode, forKey: shared.keyDarkmode)
            
            shared.userDef.synchronize()
        }
        
    }    
   
}

Solution

  • The problem is that you set the switch theme always to false instead of the value in UserDefaults.

    The shared class is not needed. This code is sufficient, and UserDefaults provides bool(forKey which returns false if the key is missing. If you need true as default value register the key-value pair.

    class ViewController: UIViewController {
        
        private let keyDarkmode = "darkMode"
    
        @IBOutlet weak var theme: UISwitch!
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let isDarkMode = UserDefaults.standard.bool(forKey: keyDarkmode)
            theme.setOn(isDarkMode, animated: false)
            overrideUserInterfaceStyle = isDarkMode ? .dark : .light
        }
    
        
        @IBAction func themeSwitch(_ sender: UISwitch) {
            overrideUserInterfaceStyle = sender.isOn ? .dark : .light
            UserDefaults.standard.set(sender.isOn,  forKey: keyDarkmode)
        }
    }
    

    Side note: Calling synchronize is not needed either.