设置包的值返回nil

我添加了一个设置包到我的应用程序,在Xcode它出现在我的项目树视图的根。

Root.plist文件如下所示:

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>StringsTable</key> <string>Root</string> <key>PreferenceSpecifiers</key> <array> <dict> <key>Type</key> <string>PSGroupSpecifier</string> <key>Title</key> <string>Service</string> </dict> <dict> <key>Type</key> <string>PSTextFieldSpecifier</string> <key>Title</key> <string>Hostname</string> <key>Key</key> <string>service_hostname</string> <!-- and so on --> 

当我在iOS上打开“设置”应用程序时,该条目出现在底部,我可以很好地显示和编辑我的设置。

但是我无法从代码中检索这些值。 这是我的代码:

 static func loadSettings() { let ud = NSUserDefaults.standardUserDefaults() ud.synchronize() Settings.hostName = ud.stringForKey("service_hostname") // etc } 

我也试过ud.objectForKeyud.valueForKey – 都返回nil

设置Settings.hostName后,尽pipe我在Settings应用程序中设置了显式值,但Xcodedebugging器报告它的值为nil

我看到这个线程( iPhone应用程序:如何从root.plist获取默认值? )有人发布了一个Objective-C代码块,手动将Root.plist文件直接加载到NSMutableDictionary并调用NSUserDefaults.standardUserDefaults().registerDefaults但这似乎是一个黑客(我不能让它在Swift中工作,因为编译器说, stringByAppendingPathComponent不存在了)

为什么不是NSUserDefaults从设置应用程序中获取设置?

显然原因是如果我的plist设置已经定义了默认值,并且用户没有明确设置一个值,那么Settings应用程序中显示的值将是plist文件的默认值,但是NSUserDefaults API仍然会返回nil

不幸的是,这意味着如果默认值是有意义的(例如默认的Web服务地址URI:“ http://www.example.com ”),它必须在我的项目中存在两次:默认情况下,在plist和我的程式码:

Root.plist:

  <dict> <key>Key</key> <string>mySettingKey</string> <key>Title</key> <string>Some address</string> <key>Type</key> <string>PSTextFieldSpecifier</string> <key>DefaultValue</key> <string>http://www.example.com</string> <key>IsSecure</key> <false /> <key>KeyboardType</key> <string>Alphabet</string> </dict> 

Program.swift:

 let ud = NSUserDefaults.standardUserDefaults() ud.synchronize() var mySettingValue = ud.stringForKey("mySettingKey") if mySettingValue == nil { mySettingValue = "http://www.example.com" } 

这是令人惊讶的。

你应该注册你的默认值,以便它会同步。 来源于这里

 // Swift 3 var appDefaults = Dictionary<String, AnyObject>() appDefaults["mySettingKey"] = "http://www.example.com" // Default Value UserDefaults.standard.register(appDefaults) UserDefaults.standard.synchronize() let mySettingValue = UserDefaults.standard.string(forKey: "mySettingKey") 

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

默认值可以从Settings.bundle并添加到UserDefaults中。 可以在didFinishLaunchingWithOptions AppDelegate.swift调用以下函数。

 func setDefaultsFromSettingsBundle() { //Read PreferenceSpecifiers from Root.plist in Settings.Bundle if let settingsURL = Bundle.main.url(forResource: "Root", withExtension: "plist", subdirectory: "Settings.bundle"), let settingsPlist = NSDictionary(contentsOf: settingsURL), let preferences = settingsPlist["PreferenceSpecifiers"] as? [NSDictionary] { for prefSpecification in preferences { if let key = prefSpecification["Key"] as? String, let value = prefSpecification["DefaultValue"] { //If key doesn't exists in userDefaults then register it, else keep original value if UserDefaults.standard.value(forKey: key) == nil { UserDefaults.standard.set(value, forKey: key) NSLog("registerDefaultsFromSettingsBundle: Set following to UserDefaults - (key: \(key), value: \(value), type: \(type(of: value)))") } } } } else { NSLog("registerDefaultsFromSettingsBundle: Could not find Settings.bundle") } }