DEV Community

Cover image for Data Persistence in Swift: UserDefaults
mrcflorian
mrcflorian

Posted on • Edited on

1 1

Data Persistence in Swift: UserDefaults

There are multiple ways to persist data in iOS apps. In this article, we are going to talk about UserDefaults. In Swift, UserDefaults API can be used to store small amounts of information about the application or user's settings.

swift userdefaults

For instance, the user should be able to specify the default playback speed or currency that you should display when presenting some stock data. These preferences should be application specific and should be persistent between app launches. However, this data storage is wiped out when users delete the app, so the data is not persistent across app installs.

UserDefaults Example

class UserRepository {
    enum Key: String, CaseIterable {
        case name, avatarData
        func make(for userID: String) -> String {
            return self.rawValue + "_" + userID
        }
    }
    let userDefaults: UserDefaults
    // MARK: - Lifecycle
    init(userDefaults: UserDefaults = .standard) {
        self.userDefaults = userDefaults
    }
    // MARK: - API
    func storeInfo(forUserID userID: String, name: String, avatarData: Data) {
        saveValue(forKey: .name, value: name, userID: userID)
        saveValue(forKey: .avatarData, value: avatarData, userID: userID)
    }

    func getUserInfo(forUserID userID: String) -> (name: String?, avatarData: Data?) {
        let name: String? = readValue(forKey: .name, userID: userID)
        let avatarData: Data? = readValue(forKey: .avatarData, userID: userID)
        return (name, avatarData)
    }

    func removeUserInfo(forUserID userID: String) {
        Key
            .allCases
            .map { $0.make(for: userID) }
            .forEach { key in
                userDefaults.removeObject(forKey: key)
        }
    }
    // MARK: - Private
    private func saveValue(forKey key: Key, value: Any, userID: String) {
        userDefaults.set(value, forKey: key.make(for: userID))
    }
    private func readValue<T>(forKey key: Key, userID: String) -> T? {
        return userDefaults.value(forKey: key.make(for: userID)) as? T
    }
}
Enter fullscreen mode Exit fullscreen mode

Benefits

  • UserDefaults is easy to use, with a simple clean API
  • UserDefaults is thread-safe (you can read and write values from any thread)
  • UserDefaults is shared between the app and the app extensions

Disadvantages

  • Collisions can happen easily
  • Lack of data encryption
  • Not persistent across app installs

Stay tuned for the other articles where I will present a few alternatives to UserDefaults, trying to mitigate some of the limitations outlined above.

Resources

Sentry mobile image

Improving mobile performance, from slow screens to app start time

Based on our experience working with thousands of mobile developer teams, we developed a mobile monitoring maturity curve.

Read more

Top comments (0)

nextjs tutorial video

Youtube Tutorial Series 📺

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay