Ios SwiftUI使用@AppStorage进行设置的最佳实践:如何在加载@AppStorage之前读取用户默认值?

Ios SwiftUI使用@AppStorage进行设置的最佳实践:如何在加载@AppStorage之前读取用户默认值?,ios,macos,swiftui,Ios,Macos,Swiftui,我使用@AppStorage在设置视图中保存一些首选项,就像苹果推荐的那样: 我还有一个主窗口,它会在用户打开设置视图之前读取一些首选项,然后我会读取“错误”的UserDefaults,因为预期值不会写入UserDefaults,因为设置视图尚未加载 例如: // Settings view struct SettingsView: View { @AppStorage("x") var x = 5 // give preference a default value

我使用@AppStorage在设置视图中保存一些首选项,就像苹果推荐的那样:

我还有一个主窗口,它会在用户打开设置视图之前读取一些首选项,然后我会读取“错误”的UserDefaults,因为预期值不会写入UserDefaults,因为设置视图尚未加载

例如:

// Settings view
struct SettingsView: View {
   @AppStorage("x") var x = 5  // give preference a default value
   ...
}

// Main view
struct MainView: View {

    func foo() {
        let x = UserDefaults.standard.double(forKey: "x")
        // x is not the default value I expect
    }
}
我知道可能的解决办法:

  • 在应用程序启动时,检查UserDefaults是否为nil,如果是,则使用默认值写入它们
  • 读取UserDefaults时,检查UserDefaults是否为nil,如果是,则改为读取默认值

  • 有没有更好的方法来处理?谢谢

    UserDefaults
    提供了一个名为
    register
    的方法,该方法使用“default”(无双关语)值加载它。这些值仅在
    UserDefaults
    中实际存储的键没有任何值的情况下使用

    我发现在应用程序启动时使用我的AppDelegate中应用程序包中的plist中的值填充它很有用(例如在
    didfishLaunchingWithOptions
    ——如果使用SwiftUI生命周期,您仍然可以这样做:):

    从文档中:

    注册域的内容未写入磁盘每次应用程序启动时都需要调用此方法。您可以将plist文件放在应用程序的Resources目录中,并使用从该文件读取的内容调用register(默认值:)

    使用此系统,您无需检查自己的
    nil
    值并决定是否加载默认值。并且,当您从
    UserDefaults
    执行检查读取时,您将在其中看到预填充的值

    if let prefs = Bundle.main.path(forResource: "defaults", ofType: "plist"), 
        let dict = NSDictionary(contentsOfFile: prefs) as? [String : Any] {
      UserDefaults.standard.register(defaults: dict)
    }