我在我的应用中添加了一个设置包,在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.objectForKey
和ud.valueForKey
- 两者都返回nil
。
设置Settings.hostName
Xcode调试器报告后,尽管我在“设置”应用中设置了显式值,但其值为nil
。
我看到了这个帖子(iPhone App : How to get default value from root.plist?),其中有人发布了一大块Objective-C代码,可以将Root.plist
文件直接手动加载到NSMutableDictionary
并调用NSUserDefaults.standardUserDefaults().registerDefaults
但是这似乎是一个黑客(我无法让它在Swift中工作,因为编译器说stringByAppendingPathComponent
不再存在)
为什么没有NSUserDefaults
从“设置”应用中获取设置?
答案 0 :(得分:12)
默认值可以从Settings.bundle
获取并添加到UserDefaults。可以在AppDelegate.swift
的{{1}}中调用以下函数。
didFinishLaunchingWithOptions
答案 1 :(得分:11)
显然原因是,如果response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
中的我的设置已定义默认值且用户未明确设置值,那么“设置”应用中显示的值将是plist
中的默认值文件,但plist
API仍会返回NSUserDefaults
。
不幸的是,这意味着如果默认值是有意义的(例如默认的Web服务地址URI:“nil
”),它必须在我的项目中存在两次:作为http://www.example.com
中的默认值在我的程序代码中:
Root.plist:
plist
Program.swift:
<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>
这令人惊讶。
答案 2 :(得分:7)
您应该注册默认设置,以便同步。 source from here
// 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文件中,并将其注册到默认数据库,如上所示。
答案 3 :(得分:0)
您需要从Settings.bundle中手动读取默认值,并将它们添加到UserDefaults注册域,这可以通过UserDefaults.register()
完成。通过使用注册域,这些值将保存在内存中(易失性),因此不需要调用UserDefaults.synchronize()
。
以下几行Swift可以完成工作:
// Register the default values from Settings.bundle
if let settingsURL = Bundle.main.url(forResource: "Root", withExtension: "plist", subdirectory: "Settings.bundle"),
let settingsRootDict = NSDictionary(contentsOf: settingsURL),
let prefSpecifiers = settingsRootDict["PreferenceSpecifiers"] as? [NSDictionary],
let keysAndValues = prefSpecifiers.map({ d in (d["Key"], d["DefaultValue"]) }) as? [(String, Any)] {
UserDefaults.standard.register(defaults: Dictionary(uniqueKeysWithValues: keysAndValues))
}