如何将 plist 注册到 NSUserDefaults?

How do I register a plist to NSUserDefaults?

我想做的是将我的初始用户默认值存储在 plist 中,然后在应用程序首次加载时将它们读入 NSUserDefaults。

我发现了几个 到目前为止对我有帮助,但是我似乎无法找到为什么我在展开时发现 nil 的答案。显然我遗漏了一些东西,所以我的问题是:

如何正确地将 plist 注册到 NSUserDefaults?

我已经使用我的默认设置创建了一个 plist。我想从 plist 中读取并将它们注册到 NSUserDefaults 中。

settings.plist

ViewController.swift

class ViewController: UIViewController {

    let userDefaults = NSUserDefaults.standardUserDefaults()

    override func viewDidLoad() {
        super.viewDidLoad()
        let prefs = NSBundle.mainBundle().pathForResource("Settings", ofType: "plist")
        let dict = NSDictionary(contentsOfFile: prefs!)

        if let dictionary = dict {
            println("Contents of file unwrapped: \(dictionary)") // <---------
            let defaults : NSDictionary! = dictionary.valueForKey("Root") as? NSDictionary
            println("defaults: \(defaults)") // <---------
            userDefaults.registerDefaults(defaults as! [NSObject : AnyObject])
            userDefaults.synchronize()
        }

        if let unwrapDict = dict {

            var myValue = unwrapDict.objectForKey("Boolean Switch 1") as! Bool
            println("pulled from pList \(myValue)")
        }
    }
}

我确定您已经注意到我正在从我的 plist 中寻找密钥 'Root'...

let defaults : NSDictionary! = dictionary.valueForKey("Root") as? NSDictionary

我也尝试过将其他值传递给它,例如 "Boolean Switch 1" 并转换为不同的类型。但我的尝试并没有改变结果。

这是我的两个 println() 日志的控制台输出。

根据 Apple 文档,如果您不更改任何设置值,则从 NSUserDefaults 读取的值为 nil 或 0。在您的代码中,当您从 NSUserDefaults 读取值时,您应该将其设置为默认值。

经过一天的修改代码后,我终于能够将我的 plist 输入到 NSUserDefaults 中。我对最终结果并不满意,因为我注意到 registerDefaults 实际上 没有做 任何事情。

所以我决定 post 我的工作代码 Code Review to see if there were any parts of my code that weren't necessary. It turns out that registerDefualts indeed was not necessary, here's an excerpt from the Alex's 回答我的问题。

This line: userDefaults.registerDefaults(dict as! [NSObject : AnyObject]) does not actually set the information on the NSUserDefaults storage file on disk. All it does is tell NSUserDefaults the default values to be used when a key doesn't yet exist on disk.

所以说了这么多,我将 post 工作代码。我应该注意,正如 nhgrif 向我指出的那样,ViewController 实际上 不是 放置此代码的地方,更好的地方是application(_:didFinishLaunchingWithOptions:).

中的 appDelegate

ViewController:

class ViewController: UIViewController {

    let userDefaults = NSUserDefaults.standardUserDefaults()

    override func viewDidLoad() {
        super.viewDidLoad()

        let prefs = NSBundle.mainBundle().pathForResource("Settings", ofType: "plist")
        let dict = NSDictionary(contentsOfFile: prefs!)
        userDefaults.setObject(dict, forKey: "defaults")          
        userDefaults.synchronize()

        // this just toggles the aBool value
        if let defaults = userDefaults.valueForKey("aBool") as? NSNumber {

            if defaults as NSObject == 1 {
                println("inside the conditional: \(defaults)")
                userDefaults.setValue(0, forKey: "aBool")
                userDefaults.synchronize()
                println("Setting aBool to true")
            } else {
                userDefaults.setValue(1, forKey: "aBool")
                userDefaults.synchronize()
                println("setting aBool to false")
            }
        }
    }
}