返回Swift / Xcode 6中设置包开关的值

时间:2015-05-13 14:15:48

标签: xcode swift ios8

我很难返回存储的布尔键的值。

我的root.plist看起来像这样:

enter image description here

我在AppDelegate中得到了这个:

    let a = NSUserDefaults.standardUserDefaults().boolForKey("sound")

    if a { // This is where it breaks
        println("sound is on")
    }

任何想法我做错了什么?

3 个答案:

答案 0 :(得分:12)

首先,您应该注册默认值,以便所有内容都同步并分配默认值。然后你就会知道存在一个值。这些值在启动时不会自动同步。

var appDefaults = Dictionary<String, AnyObject>()
appDefaults["sound"] = false
NSUserDefaults.standardUserDefaults().registerDefaults(appDefaults)
NSUserDefaults.standardUserDefaults().synchronize()

let a = NSUserDefaults.standardUserDefaults().boolForKey("sound")

if a { // This is where it breaks
    println("sound is on")
}

以下是相关文章的摘录。

<强> When Your App Uses a Settings Bundle

请记住,您还应该使用registerDefaults:当您的应用使用设置包时。由于您已在设置包的plist中指定了默认值,因此您可能希望应用自动选择这些值。但事实并非如此。设置包中包含的信息仅由iOS Settings.app读取,绝不会被您的应用读取。 为了让您的应用程序使用与Settings.app中显示的相同的默认值,您必须手动将用户默认值及其默认值复制到单独的plist文件中,并将其注册到默认数据库,如上所示。

HERE是直接来自Apple的相关讨论。

注册默认值

讨论

如果没有注册域,则使用指定的字典创建一个注册域,并将NSRegistrationDomain添加到搜索列表的末尾。 注册域的内容不会写入磁盘;每次应用程序启动时都需要调用此方法。您可以将plist文件放在应用程序的Resources目录中,并使用从该文件中读入的内容调用registerDefaults:

答案 1 :(得分:1)

使用此:

    var myDict: NSDictionary?
// Read from the Configuration plist the data to make the state of the object valid.
    if let path = NSBundle.mainBundle().pathForResource("root", ofType: "plist") {
        myDict = NSDictionary(contentsOfFile: path)
    }

    // Set the values to init the object
    if let dict = myDict {
        if let a = dict["sound"] as? Bool {
         if a { 
            println("sound is on")
          }
        }
    }

答案 2 :(得分:0)

我来这篇帖子的原因是今天我遇到了同样的问题,对此注释并不十分满意:

为了使您的应用使用与Settings.app内所示相同的默认值,您必须手动将用户默认键及其默认值复制到单独的plist文件中,并如上所述将其注册到默认数据库中。

我认为必须有更多的DRY解决方案,因此我做了以下扩展。遍历Settings.bundle的plists(包括Child plists)并注册找到的所有DefaultValues。也可以在this gist中使用。

extension UserDefaults {

    static func syncSettingsBundle() {
        if let bundlePath = Bundle.main.path(forResource: "Settings", ofType: "bundle"),
            let plistPath = URL(string: bundlePath)?.appendingPathComponent("Root.plist").absoluteString {

            let defaultDefaults = UserDefaults.defaultsForPlist(path: plistPath, defaults: [:])
            UserDefaults.standard.register(defaults: defaultDefaults)
        }
    }

    static private func defaultsForPlist(path: String, defaults: [String: Any]) -> [String: Any] {
        var mutableDefaults = defaults
        if let plistXML = FileManager.default.contents(atPath: path) {
            do {
                let plistData = try PropertyListSerialization.propertyList(from: plistXML,
                                                                           options: .mutableContainersAndLeaves,
                                                                           format: nil) as! [String:AnyObject]
                if let prefs = plistData["PreferenceSpecifiers"] as? Array<[String: Any]> {
                    prefs.forEach { (pref: [String : Any]) in
                        if let key = pref["Key"] as? String,
                            let value = pref["DefaultValue"] {
                            mutableDefaults[key] = value
                        } else if let type = pref["Type"] as? String,
                            type == "PSChildPaneSpecifier",
                            let file = pref["File"] as? String,
                            let childPath = URL(string: path)?
                                .deletingLastPathComponent()
                                .appendingPathComponent(file)
                                .absoluteString {
                            mutableDefaults = UserDefaults.defaultsForPlist(path: childPath, defaults: mutableDefaults)
                        }
                    }
                } else {
                    print("Error no PreferenceSpecifiers in \(path)")
                }
            } catch {
                print("Error reading plist: \(error) in \(path)")
            }
        } else {
            print("No plist found found at \(path)")
        }
        return mutableDefaults
    }
}