BigUIUserPreferences

main

A strongly typed SwiftUI wrapper for UserDefaults
notsobigcompany/BigUIUserPreferences

BigUIUserPreferences

A strongly typed Swift and SwiftUI wrapper for UserDefaults.

This package adds two new interfaces for working with UserDefaults:

  1. A @UserPreference property wrapper for SwiftUI views:
@UserPreference(MiniSidebarKey.self) private var enabled
  1. A subscript interface for UserDefaults:
UserDefaults.standard[MiniSidebarKey.self] = true

By tightly coupling key names and default values together with UserPreferenceKey you eliminate the possibility of key typos, differing defaults, and type mismatches. This package also adds support for Codable and Date types.

Installation

Add this repository to your Package.swift file:

.package(url: "https://github.com/notsobigcompany/BigUIUserPreferences.git", from: "1.0.0")

If you’re adding to an Xcode project go to File -> Add Packages, then link the package to your required target.

Getting Started

First declare a UserPreferenceKey type and specify a default value:

struct MiniSidebarKey: UserPreferenceKey {
    static let defaultValue: Bool = false
}

Tip

Both EnvironmentKey and UserPreferenceKey have the exact same type requirements.

SwiftUI

Using the key you can access the value inside of a SwiftUI view with the @UserPreference property wrapper:

struct MiniSidebarToggle: View {
    
    @UserPreference(MiniSidebarKey.self) private var enabled
    
    var body: some View {
        Toggle(isOn: $enabled) {
            Text("Enable Minibar")
        }
    }
}

Unlike AppStorage you don't need to specify the type or default value.

The wrapper always reflects the latest value in the UserDefaults and invalidates the view on any external changes.

Subscript

You can also access the value by using the subscript interface directly on UserDefaults itself:

let defaults = UserDefaults.standard 
defaults[MiniSidebarToggle.self] = true 

var isMiniBarEnabled = defaults[MiniSidebarToggle.self]
// true
print(isMiniBarEnabled)

Note

If there's no value in the store the subscript API will return the key's default value, rather than the store's default.

Supported Types

  • String
  • Int
  • Double
  • Data
  • Date
  • URL
  • RawRepresentable where RawValue is Int
  • RawRepresentable where RawValue is String
  • Codable when wrapped in CodablePreferenceValue

Codable Values

You can store small Codable values by wrapping the value in CodablePreferenceValue:

struct User: Codable, Equatable {
    // ...
}

struct LoggedInUserKey: UserPreferenceKey {
    static var defaultValue: CodablePreferenceValue<User?> = .init()
}

Important

The wrapper itself cannot be optional, but the underlying wrapped type can be.

You can then access the underlying value by calling wrappedValue:

@UserPreference(LoggedInUserKey.self) private var user

var body: some View {
    if let user = user.wrappedValue {
        Text("Hello \(user.username)")
    }
}

Explicit Key Names

By default UserPreferenceKey uses an auto-generated key name to lookup values inside the store. If you wish to use an explicit key name instead (say, to support pre-existing values) adopt ExplicitlyNamedUserPreferenceKey and return a name:

struct MyExplicitPreferenceKey: ExplicitlyNamedUserPreferenceKey {
    static let defaultValue: Bool = false
    // The name of the value inside the store
    static let name: String = "my_explicit_key"
}

Requirements

  • iOS 14.0
  • macOS 11.0

License

Copyright 2023 NOT SO BIG TECH LIMITED

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Description

  • Swift Tools 5.9.0
View More Packages from this Author

Dependencies

  • None
Last updated: Fri Apr 12 2024 10:02:48 GMT-0900 (Hawaii-Aleutian Daylight Time)