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