Where to place the .register() method to set an initial/default value for UserDefaults?

Viewed 420

I am currently struggling to figure out where to correctly place the .register() method to set an initial/default value for UserDefaults (on every launch of the app).

Here is where I tried to initialize it in the "App" file that Xcode generated with the project:

import SwiftUI

@main
struct TestApp: App {

    init() {
        //Sets default values for the user defaults that have not yet been set and should not return 0/false
        UserDefaults.standard.register(defaults: [
                "selectedRoundLength": 1
            ]
        )
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

However, this doesn't really seem to do the trick. Does anyone have input on this one?

2 Answers

This init is called before UIApplication has set up yet, so if you want to register defaults (which can be done from plist of big dictionary) it should be done via app delegate adapter.

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {

        // Register defaults here !!
        UserDefaults.standard.register(defaults: [
                "selectedRoundLength": 1
                // ... other settings
            ]
        )

        return true
    }
}

@main
struct TestApp: App {

    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

If your minimum target is iOS 14, you can use @AppStorage to save your value in UserDefaults and start with an initial value. You don't particularly need to add this @AppStorage value in the @main to initialise it. You can just call it in any SwiftUI view or Observable class where you really need it. It will have this initial value if none has been saved.

import SwiftUI

@main
struct TestApp: App {

  // This is UserDefaults starting in iOS 14.
  @AppStorage("selectedRoundLength") var selectedRoundLength = 1

  var body: some Scene {
    WindowGroup {
      ContentView()
    }
  }
}
Related