All Articles

UserDefaults Read & Write Design Pattern

So you finally mastered the art of UserDefaults, but as with any modern app, your codebase grows and grows. It then becomes harder and harder to organize where exactly to place your UserDefaults.

This is a design pattern I’ve been using that keeps all the UserDefaults in one place and essentially keeps everything organized.

class Defaults {
    
    private static let USER_DEFAULT_ONBOARDING = "onboarding"
    private static let USER_DEFAULT_LAST_UPDATED = "last_updated"
    
    fileprivate static var userDefault: UserDefaults {
        get {
            return Foundation.UserDefaults.standard
        }
    }
    
    static var isOnboarded: Bool {
        get {
            let defaults = Defaults.userDefault
            if defaults.object(forKey: USER_DEFAULT_ONBOARDING) == nil {
                return false
            }
            return defaults.integer(forKey: USER_DEFAULT_ONBOARDING) == 0 ? false : true
        }
    }
    
    static var lastUpdated: Date? {
        get {
            return Defaults.userDefault.object(forKey: USER_DEFAULT_LAST_UPDATED) as? Date
        } set {
            if let newValue = newValue {
                Defaults.userDefault.set(newValue, forKey: USER_DEFAULT_LAST_UPDATED)
            } else {
                Defaults.userDefault.removeObject(forKey: USER_DEFAULT_LAST_UPDATED)
            }
        }
    }
}

So simply to use it:

/// Get Example
if !Defaults.isOnboarded {
   /// do something
}
/// Set Example
Defaults.isOnboarded = true

Essential this design pattern makes a user default look like a variable, but with the added benefit of persistance.

Published 9 Oct 2017