Follow

: Stop using AppStorage directly. It’s prone to typos, value mismatches and more.

Instead give yourself strongly typed keys and associated defaults, à la EnvironmentValues.

I’ve published my implementation as a package, but you can just as easily wrap AppStorage yourself with a few dozen lines.

github.com/notsobigcompany/Big

@phill I’m doing almost the same by introducing a „TypedKey“, but added a buch of initializers to AppStorage. Upside: It’s as familiar as possible to anyone who knows AppStorage.

TypedKey is also used everywhere where having typed values and potentially default values makes sense. I strongly wonder why it’s not part of the system tbh.

@gernot very cool and similar! Great minds :-)

And yes it’s curious AppStorage works the way it does when the EnvironmentValues system is sat right there.

@gernot @phill I am trying to understand if the benefits are mostly if you have default values because for optionals it seems that there isn’t much benefit. From the screenshot i didn’t see much improvements if you are already keeping your keys separate in an enum. I am genuinely curious if i am missing something here.

@keval @gernot beware that even if with an optional value the store will always return a default value. Double will return 0 if there is no entry, Bool will return false, etc. This can have subtle and unexpected consequences if you’re expecting nil.

By clearly defining your default values you’re making your codebase easier to reason with, test, etc.

@phill @keval You sure?

@AppStorage("Test") private var test: Double?

is nil as it should be if it’s not set.

@AppStorage("Test2“) private var test2: Double? = 12.0

is 12.0 if it’s not set.

The self.init(wrappedValue:) in the initialisers jus just another form of writing the exact same thing.

@gernot @keval the AppStorage interface will always return its default value, however if you access the value through the store (e.g UserDefaults.standard.double(forKey:)) you will get the store's default instead.

Yet another reason for having a common interface everywhere!
developer.apple.com/documentat

@phill @keval Ah, I think now I see what you mean. Yeah, those early attempts at non-generic „typed“ UserDefaults should be deprecated in my opinion. All those late-90s APIs have a thick layer of abandoned concepts in them.

@keval @phill The reason for having default values in keys is that they’re defined only once. AppStorage is often used twice: in the In-App settings, and a second time where it’s actually used. If you want to switch a default from say true to false you’d have to remember doing it everywhere it’s used. Alternative: You register it oldschool with UserDefaults.register(), right on the start of the app, but that’s another separate thing to remember.

Sign in to participate in the conversation
The Not So Big Company

The home of The Not So Big Company on Mastodon.