【问题标题】:Swift - How to set initial value for NSUserDefaultsSwift - 如何为 NSUserDefaults 设置初始值
【发布时间】:2016-10-16 06:44:14
【问题描述】:

我有一个名为soundSwitch 的开关,我正在使用userDefault 保存按钮的状态:

@IBAction func soundsChanged(sender: AnyObject) {
        if soundSwitch.on{
            defaults.setBool(true, forKey: "SoundActive")
            print("Sound ON")
        }else{
            defaults.setBool(false, forKey: "SoundActive")
            print("Sound OFF")
        }
    }

目前,当用户首次启动应用程序时,实际默认值最初为 false。

如果用户启动应用程序但尚未配置默认值,我该如何实现默认值。

我在Objective-C 中看到过方法,但在 Swift 中没有。从我所见,您可以以某种方式在应用程序委托中或在PList 文件中执行此操作。我该怎么做?

【问题讨论】:

标签: ios swift nsuserdefaults uiswitch


【解决方案1】:

Swift 3 语法示例

注册一个布尔默认值:

UserDefaults.standard.register(defaults: ["SoundActive" : true])

为了得到价值:

UserDefaults.standard.bool(forKey: "SoundActive")

旁注:虽然上面的代码会返回 true,但请注意,在您设置它之前,该值不会真正写入磁盘:

UserDefaults.standard.set(true, forKey: "SoundActive")

【讨论】:

  • the value isn't actually written to disk until you set it 是什么意思?这是否意味着,在以后的版本中,我是否应该永远不要设置默认值并从AppDelegate 中删除注册,因为从未手动设置,所以密钥不会检索true
  • @TomQDDRS 是正确的。引用developer.apple.com/documentation/foundation/nsuserdefaults/…:“注册域的内容没有写入磁盘;每次应用启动时都需要调用这个方法。”
【解决方案2】:

将此添加到 AppDelegate 中的 didFinishLaunchingWithOptions 方法中。正如其他一些人指出的那样,尽量不要滥用这种方法。

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    /// Here you can give default values to your UserDefault keys
    UserDefaults.standard.register(defaults: [
        "SoundActive": true,
        "someOtherKey": "Some Message"
        ])
}

【讨论】:

  • 好吧,register 方法。谢谢?
【解决方案3】:

斯威夫特 4

我更喜欢实现类似于UserDefaults.string(forKey: ) 的函数,如果未设置该值,则返回nil。结合??运算符,您不需要将任何默认值写入磁盘,除非您稍后明确设置它们。

extension UserDefaults {

    public func optionalInt(forKey defaultName: String) -> Int? {
        let defaults = self
        if let value = defaults.value(forKey: defaultName) {
            return value as? Int
        }
        return nil
    }

    public func optionalBool(forKey defaultName: String) -> Bool? {
        let defaults = self
        if let value = defaults.value(forKey: defaultName) {
            return value as? Bool
        }
        return nil
    }
}

然后您可以按如下方式检索默认值

let defaults = UserDefaults.standard
let userName = defaults.string(forKey: "Username") ?? "Happy"
let userAge = defaults.optionalInt(forKey: "Age") ?? 21
let isSmart = defaults.optionalBool(forKey: "Smart") ?? true

【讨论】:

    【解决方案4】:

    使用“registerDefaults”可以设置NSUserDefaults的默认值

    let userDefaultsDefaults = [
                "SoundActive" : true
            ]
    
    NSUserDefaults.standardUserDefaults().registerDefaults(userDefaultsDefaults)
    

    注意:把这个写在didFinishLaunchingWithOptions中,所以设置了默认值。

    在下面要检查的地方写下代码

     let onoroff = NSUserDefaults.standardUserDefaults().objectForKey("SoundActive") as! Bool!
    
     if (onoroff != nil && onoroff == false)
     {
        self.checkForAgreement()
     }
    

    【讨论】:

      【解决方案5】:

      没有特定的 swift 或应用程序委托。

      通过在 standardUserDefaults 实例上调用 registerDefaults: 来设置初始默认值。

      您可以多次进行此调用,我建议您不要在应用程序委托中执行此操作,而是在应用程序中的适当时间注册适当的详细信息,因此如果您有 1 个使用某些视图控制器/子系统默认值,然后将默认值注册为该代码的初始化的一部分。

      只有当你有一些被代码的多个不同部分使用的东西时,你才应该考虑在应用程序委托中这样做,并且只有在你没有其他合适的控制器来执行它的情况下。

      【讨论】:

      • 为什么不在应用委托中做呢?
      • 因为应用程序委托是为了特定目的而存在的,并且任意用户默认注册不是该目的的一部分@simpleBob - 作为应用程序的代表并处理应用程序级事件,仅此而已跨度>
      • 但是用户默认注册应该在其他任何事情之前完成,这就是为什么didFinishLaunchingWithOptions 会是一个相当明显的地方,它是在大多数项目中找到的地方。另外,我认为将所有默认值放在一个位置比在整个项目中使用多个 registerDefaults 更好。
      • 应该在需要之前做,而且要在合理的地方做。确保您可以在应用程序委托中执行此操作,但这不是应用程序委托的目的,这很容易,这就是大多数人这样做的原因。 @simpleBob
      • 我认为在需要时注册默认的问题是有人可能更早需要它而忘记移动注册。
      【解决方案6】:
      func lastStatus() -> Bool {
          let defaultValue = true
          if let value = default.valueForKey("SoundActive") {
              // then use it
              return value as? Bool ?? defaultValue
          } else {
              // oh, no value?
              return defaultValue
          }
      }
      

      我认为这是使用它的最佳方式。 register(defaults:) 也会有所帮助,但在文档中 Apple 建议将其用作 fallback,例如分离 no valuedefault value 的情况。看你的需要。

      【讨论】:

        【解决方案7】:

        您可以将所有UserDefaults 逻辑封装到一个属性变量中,该变量会自动注册应用程序默认值并将任何更新保存回用户默认值字典。如果应用程序的其他部分(除了开关控件)也读取或更改此状态,这将特别方便。

        Swift 5 — 第一部分执行一个闭包来初始化属性,第二部分是didSet 块,它会在属性更改时自动调用。

        var soundIsActive: Bool = {
                // Register the app default:
                UserDefaults.standard.register(defaults: ["SoundActive" : true])
        
                // Initialize the property with the current user default:
                return UserDefaults.standard.bool(forKey: "SoundActive")
            }()
            {
                didSet {
                    // Update user default when the variable is set:
                    UserDefaults.standard.set(soundIsActive, forKey: "SoundActive")
                }
            }
        

        【讨论】:

          【解决方案8】:

          如果你真的想这样做,把它放在 AppDelegate 中:

          func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
          
              let defaults = NSUserDefaults.standardUserDefaults()
              if defaults.valueForKey("SoundActive") == nil {
                  defaults.setBool(true, forKey: "SoundActive")
              }
          

          如果只是在一个viewcontroller中使用,可以考虑把代码放在viewDidLoad方法中!

          【讨论】:

          • 我认为这不是一个好方法,因为每次我启动应用程序时,它都会运行这些代码。但实际上,只是第一次需要。
          • 好的,你编辑它。但我认为最好的地方是当你使用“SoundActive”的值时,如果 nil 则为 true。
          【解决方案9】:

          如何设置默认值的通用版本:

          enum UserDefaultsKeys: String {
              case username = "kUsername"
          }
          
          extension UserDefaults {
              func optionalValue<T>(forKey key: UserDefaultsKeys) -> T? {
                  if let value = self.value(forKey: key.rawValue) {
                      return value as? T
                  }
                  return nil
              }
          }
          
          let username = defaults.optionalValue(forKey: .username) ?? ""
          

          【讨论】:

            【解决方案10】:

            把它放在 AppDelegate 的“didFinishLaunchingWithOptions”中。

            if defaults.valueForKey("launchedAlready") == true {
                   print("Not first launch.")
                }
                else {
                   defaults.setValue(true, forKey: "launchedAlready")
                    defaults.setBool(true, forKey: "SoundActive")
                    print("Sound ON")
                }
            

            【讨论】:

              猜你喜欢
              • 2011-04-03
              • 1970-01-01
              • 2022-12-18
              • 1970-01-01
              • 2023-01-30
              • 2018-09-11
              • 2019-08-22
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多