I‘d like to store my user defaults in a class. With the old Swift data flow it was possible to use it in a class. Now, with the new system (Xcode 15, Beta 2), it doesn’t work anymore. Is there any way to use it? Maybe a workaround?
This is how it worked before:
import SwiftUI
class UserInfo: ObservableObject {
@AppStorage("username") var username: String = ""
}
And now I want to use the new system:
import SwiftUI
@Observable class UserInfo {
@AppStorage("username") var username: String = ""
}
Unfortunately, it doesn’t work.
This is the way while @AppStorage is incompatible with @Observable.
@Observable
final class SomeClass {
var name: String {
get {
access(keyPath: \.name)
return UserDefaults.standard.string(forKey: "name") ?? ""
}
set {
withMutation(keyPath: \.name) {
UserDefaults.standard.setValue(newValue, forKey: "name")
}
}
}
}
Code from Swift Forums.
Other answers in this post cover, pretty much, all the real uses, but, for the sake of completeness, here’s a variant that uses the @AppStorage macro:
@Observable
class MyModel {
// Externally visible properties
@ObservationIgnored
var name: String {
get {
access(keyPath: \.name)
return _name
}
set {
withMutation(keyPath: \.name) {
_name = newValue
}
}
}
// Internal stored properties
@ObservationIgnored
@AppStorage("name")
private var _name: String = "Bob"
}
Quite verbose, but doesn’t use any external macros and quite easy to extend it to support, say, storing Codable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With