sunshinejr / SwiftyUserDefaults

Modern Swift API for NSUserDefaults
http://radex.io/swift/nsuserdefaults/static
MIT License
4.85k stars 365 forks source link

Please help me: How to add new variables to a stored struct? #234

Open BusyBoBo opened 4 years ago

BusyBoBo commented 4 years ago

This is my code

private let scUserConfigKey = DefaultsKey<UserConfig>.init("scUserConfigKey", defaultValue: UserConfig())
var kUserConfig: UserConfig {
    get { return Defaults[key: scUserConfigKey] }
    set { Defaults[key: scUserConfigKey] = newValue }
}

struct UserConfig: Codable, DefaultsSerializable {
    var isFirstLaunch: Bool = true
    var country: String = ""
    var sortType: SCSortType = .timeDESC
    var picQuality: SCPicQuality = .high
    var launchType: SCLaunchType = .document
    var layout: SCLayoutType = .collection
}

When I added sysConfig, all the values were restored to the default values.

struct UserConfig: Codable, DefaultsSerializable {
    var isFirstLaunch: Bool = true
    var country: String = ""
    var sortType: SCSortType = .timeDESC
    var picQuality: SCPicQuality = .high
    var launchType: SCLaunchType = .document
    var layout: SCLayoutType = .collection

    var sysConfig: SysConfig = SysConfig()
}

Where did I write wrong and how should I modify it? Thanks.

sunshinejr commented 4 years ago

Hey @BusyBoBo, because you assign the values it makes your struct always initialize with given values. I'd suggest making it a default values for initializer so you can allow Codable to actually get the values from the data:

struct UserConfig: Codable, DefaultsSerializable {
    var isFirstLaunch: Bool
    var country: String
    var sortType: SCSortType
    var picQuality: SCPicQuality
    var launchType: SCLaunchType
    var layout: SCLayoutType
    var sysConfig: SysConfig

    init(isFirstLaunch: Bool = true, country: String = "", sortType: SCSortType = .timeDESC, picQuality: SCPicQuality = .high, launchType: SCLaunchType = .document, layout: SCLayoutType = .collection, sysConfig: SysConfig = SysConfig()) {
        self.isFirstLaunch = isFirstLaunch
        ....
    }
}

This should help with getting both the default values on initializer but also being able to fetch the values from the encoded data.

BusyBoBo commented 4 years ago

I've tried and still not work

StevenSorial commented 4 years ago

Implement init(from decoder: Decoder) in UserConfig to override the default decoding behavior.