Skip to content

Commit

Permalink
[new post] userdefault keys
Browse files Browse the repository at this point in the history
  • Loading branch information
jessesquires committed Jul 17, 2023
1 parent 772f5fc commit f81e184
Showing 1 changed file with 23 additions and 0 deletions.
23 changes: 23 additions & 0 deletions _posts/2023-07-17-stop-prefixing-userdefaults-keys.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
layout: post
categories: [software-dev]
tags: [ios, macos]
date: 2023-07-17T08:41:13-07:00
title: Stop prefixing your UserDefaults keys
---

[`UserDefaults`](https://developer.apple.com/documentation/foundation/userdefaults) is probably one of the most popular APIs on Apple Platforms. It is a highly-optimized key-value persisted store that is backed by a property list, and it is most commonly used for saving small pieces of data like user preferences. Despite its ease-of-use, there is one common anti-pattern I see developers use often.

<!--excerpt-->

In dozens of iOS projects over the years, I find that developers are prefixing key names with the app's bundle identifier. For example, instead of naming a key `"sounds-enabled"` it will be named `"com.mycompany.MyApp.sounds-enabled"`. I am writing this post as a PSA to tell you that you **do not need to do this!**

On iOS, in your application's user data sandbox you will find the backing plist for `UserDefaults` at `~/Library/Preferences/com.mycompany.MyApp.plist`. On macOS, for a non-sanboxed app you will find the plist at the same path and for an app that _is_ sandboxed you will find the plist at `/private/var/db/receipts/com.mycompany.MyApp.plist`.

As you can see, your instance of `UserDefaults` is **already** namespaced by your app's bundle identifier! Prefixing your keys is redundant. So please --- do not prefix your key names with your app's bundle identifier!

{% include break.html %}

You might argue that prefixing key names is harmless, and that could be true sometimes. However, there are [known issues](https://github.com/jessesquires/Foil/pull/61#issuecomment-1253147705) with `UserDefaults` [key-value observing](https://developer.apple.com/documentation/foundation/userdefaults#2926902) if key names have periods in the name --- KVO does not work in that scenario. Furthermore, if you use debug tools (like [FLEX](https://github.com/FLEXTool/FLEX)) that allow you to inspect the values saved in `UserDefaults` or if you manually open the plist (which is just XML) to examine it, it gets really cumbersome to search and read through if every single key is prefixed with the same ~30 characters.

Lastly, if you are convinced to drop the unnecessary prefixes, beware that you will need to write migration code to save your values from the old key to the new one, otherwise you will lose data.

0 comments on commit f81e184

Please sign in to comment.