I'm currently refactoring some old code to store UserDefaults
via a @propertyWrapper
(using this generic version).
I do store some data for different layers that share some common properties. In order to implement this, I created a protocol (CommonInfo
) to which each struct
conforms.
protocol CommonInfo {
var isEnabled: Bool { get set }
// ...
}
struct PrefsInfo {
struct Location: CommonInfo, Codable {
var isEnabled: Bool
}
struct Message: CommonInfo, Codable {
var isEnabled: Bool
var message: String
}
@Storage(key: "LayerLocation", defaultValue: Location(isEnabled: true))
static var location: Location
@Storage(key: "LayerMessage", defaultValue: Message(isEnabled: false, message: "Hello There!"))
static var message: Message
}
This work great, I can read and write to UserPreferences this way :
PrefsInfo.location.isEnabled = false
But in order to make the code a bit more generic with more layer types, I thought I could add an enum:
// Lists each type of layers
enum InfoType: String, Codable {
case location, message // ...
}
and something like this to PrefsInfo
:
// Helper to quickly access a given struct
static func ofType(_ type: InfoType) -> CommonInfo {
switch type {
case .location:
return location
case .message:
return message
}
}
While this work to get the value, I cannot write to UserDefaults using this :
PrefsInfo.ofType(.location).isEnabled = false
The compiler throwing a Cannot assign to property: function call returns immutable value
.
Is there a better way to access the given struct in a generic fashion, via this enum
?