Friday, April 2, 2021 [Tweets] [Favorites]

“Foil” UserDefaults Property Wrapper

Jesse Squires (tweet):

UserDefaults is one of the most misused APIs on Apple platforms. Specifically, most developers do not handle default values correctly. In fact, I have never worked on a single production codebase at a company where this was done accurately. Most libraries get it wrong, too.


There are a few libraries that currently provide a property wrapper for UserDefaults. However, the ones that I know about each have a combination of the following issues: (1) default values are not registered, (2) optionals are not handled nicely, (3) the library is extremely complicated for such a simple task.

I like his approach. Mine differs in that:



Mark Lilback

My Cocoa projects have always had a resource named DefaultDefaults.plist which is loaded into the registration domain. Defining initial/default values in code has always seemed like a code smell to me.

@Mark I like doing it in code this way because then the compiler can check that each key has a default value. With a separate plist file, there are two separate places to update and keep in sync, and there’s the chance of mistyping one of the keys so they don’t match. Also, I often want a different default value depending on the version of macOS or some other factor, and that’s easier to do in code.

I’m also a fan of establishing initial values in code instead of registering them via a separate plist file, for all the reasons Michael stated. Though I rarely found a need to cache any values except in very frequently called code, eg: drawing code that consulted user defaults.

@Martin Yes, I am primarily thinking of drawing code. In Big Sur, navigating the message list in Mail feels a lot slower to me, and when I sampled it this seems to be partially because it’s repeatedly reading multiple defaults (e.g. the blocked sender setting) for each message.

Stay up-to-date by subscribing to the Comments RSS Feed for this post.

Leave a Comment