Initialization doesn't call the override class function for property wrapper

78 Views Asked by At

I have a base class and a derived class... the base class has a class function userDefaultKeyPrefix() which indicates the user defaults key for user default storage using a wrapper

however the AdvancedManager class ends up with the BaseManager class value of userDefaultKeyPrefix() "BASE.someVar" instead of "ADVANCED.someVar"

Why is this happening and how to achieve the desired outcome so the keys are given by the class

The init of the someVar is called as the Base class, not the Advanced

class BaseManager {

    class func userDefaultKeyPrefix() -> String {
        return "BASE"
    }
    
    @UserDefault(userDefaultKeyPrefix() + ".someVar", defaultValue: false) var someVar: Bool

}

class AdvancedManager: BaseManager {

    override class func userDefaultKeyPrefix() -> String {
        return "ADVANCED"
    }
    
}

@propertyWrapper
struct UserDefault<T> {
    let key: String
    let defaultValue: T
    
    init(_ key: String, defaultValue: T) {
        self.key = key
        self.defaultValue = defaultValue
    }

    var wrappedValue: T {
        get {
            return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
        }
        set {
            //let oldValue = wrappedValue
            UserDefaults.standard.set(newValue, forKey: key)
            UserDefaults.standard.synchronize()
        }
        
    }
    
}

UPDATE: This bellow works (the key is the "lazy") as expected, but defeats the clean code of a property wrapper

func prefix() -> String {
    return String(describing: type(of: self))
}

lazy var _someVar = UserDefault(self.prefix() + ".someVar", defaultValue: "DEFAULT")
var someVar: String {
    get {
        return _someVar.wrappedValue
    }
    set {
        _someVar.wrappedValue = newValue
    }
}

Any better solutions are welcome as answer

0

There are 0 best solutions below