我创建了一个包含大约8个切换开关的设置包。我想要做的是从设置包中获取默认值。目前我现在有这两种方法:
public static void registerUser(String email, String password) {
FirebaseAuth.getInstance().createUserWithEmailAndPassword(email,
password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success. Do things
} else {
// If sign in fails
Log.d("AuthEngineDebugger", "Something went wrong");
}
}
});
}
我在viewDidLoad中调用这些方法
func registerSettingsBundle(){
let appDefaults = [String:AnyObject]()
UserDefaults.standard.register(defaults: appDefaults)
UserDefaults.standard.synchronize()
}
func updateDisplayFromDefaults(){
let defaults = UserDefaults.standard
let update_lot = defaults.bool(forKey: "update_lot")
print(update_lot)
}
然而,这并没有得到我的默认值(都是真的,但它们都返回false)。如果我关闭应用程序,打开设置,调整设置并重新打开应用程序,这会产生正确的值。有没有获得默认设置?我走了阅读plist的路线,但如果我更改了设置包中的设置,它就不会生效。
答案 0 :(得分:9)
为了演示,我们假设您在设置包中有两个开关。一个默认值设置为YES
,另一个默认值设置为NO
。
如果您希望能够从应用中的Settings.bundle
访问UserDefaults
中定义的默认值,则必须先注册它们。不幸的是,iOS不会为你做这件事,你必须自己照顾它。
以下方法扫描与Root.plist
相关联的Settings.bundle
,并为您的首选项标识符注册默认值。
func registerDefaultsFromSettingsBundle()
{
let settingsUrl = Bundle.main.url(forResource: "Settings", withExtension: "bundle")!.appendingPathComponent("Root.plist")
let settingsPlist = NSDictionary(contentsOf:settingsUrl)!
let preferences = settingsPlist["PreferenceSpecifiers"] as! [NSDictionary]
var defaultsToRegister = Dictionary<String, Any>()
for preference in preferences {
guard let key = preference["Key"] as? String else {
NSLog("Key not fount")
continue
}
defaultsToRegister[key] = preference["DefaultValue"]
}
UserDefaults.standard.register(defaults: defaultsToRegister)
}
我建议尽早运行它。您将确保应用的所有部分都有默认值。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
registerDefaultsFromSettingsBundle()
let one = UserDefaults.standard.bool(forKey: "switch_one")
let two = UserDefaults.standard.bool(forKey: "switch_two")
NSLog("One: \(one), Two: \(two)")
return true
}
答案 1 :(得分:5)
这不会得到我的默认值(这些都是真的,但是它们 所有都返回false)
看起来您有一个切换开关,在设置包中显示为ON,当您读取包时,您将获得所有错误值。
如果是这种情况,那么你在这里遗漏了一些东西。
在设置bundle(Root.plist)时,我们有“Default Value”字段,这与切换开关的实际默认值无关。这只是一个切换的视觉指示器。 您可以在plist中将“默认值”设置为“YES”,但是当您尝试读取该值时,您将最终获得 false 。
我在Root.plist中将提醒的默认值设置为是,更新 否 因此,当应用程序启动时,它会显示如上所示。
但是当我尝试阅读这些默认值时 - 它同时为 false 。
func getDefaults() {
let stanDefaults = UserDefaults.standard
print("Default value of Update - \(stanDefaults.bool(forKey: "update_lot_pref"))")
print("\nDefault value of Reminder - \(stanDefaults.bool(forKey: "reminder_pref"))")
}
Update的默认值 - false Reminder的默认值 - false
现在,如果要同步这些值 - Root.plist中的默认值和默认值 - 那么您必须以编程方式设置它。
func setApplicationDefault() {
let stanDefaults = UserDefaults.standard
let appDefaults = ["reminder_pref": true]
stanDefaults.register(defaults: appDefaults)
stanDefaults.synchronize()
}
在我的Root.plist中,我的默认值为 YES ,而且当viewDidload我将此首选项值设置为 true 时。当我跑它时,给我
提醒的默认值 - true
这就是我的Root.plist的样子。
希望它有所帮助。
答案 2 :(得分:2)
添加LatinKeyboard
的通知,如下所示:
UserDefaults.didChangeNotification
答案 3 :(得分:1)
这是一个基于@Kamil的答案(非常感谢),它不依赖NSDictionary
并使用PropertyListSerialization
。
func registerDefaultsFromSettingsBundle() {
let settingsName = "Settings"
let settingsExtension = "bundle"
let settingsRootPlist = "Root.plist"
let settingsPreferencesItems = "PreferenceSpecifiers"
let settingsPreferenceKey = "Key"
let settingsPreferenceDefaultValue = "DefaultValue"
guard let settingsBundleURL = Bundle.main.url(forResource: settingsName, withExtension: settingsExtension),
let settingsData = try? Data(contentsOf: settingsBundleURL.appendingPathComponent(settingsRootPlist)),
let settingsPlist = try? PropertyListSerialization.propertyList(
from: settingsData,
options: [],
format: nil) as? [String: Any],
let settingsPreferences = settingsPlist[settingsPreferencesItems] as? [[String: Any]] else {
return
}
var defaultsToRegister = [String: Any]()
settingsPreferences.forEach { preference in
if let key = preference[settingsPreferenceKey] as? String {
defaultsToRegister[key] = preference[settingsPreferenceDefaultValue]
}
}
UserDefaults.standard.register(defaults: defaultsToRegister)
}
所以对于这样的Root.plist
:
... defaultsToRegister
将是:
这里还有the new compactMapValues()
API in Swift 5可能对您没有帮助。
答案 4 :(得分:0)
我确实对你所问的问题有点麻烦,但听起来你已经创建了一个设置包plist,它指定一些默认值如果未定义则为“true”(如果用户没有'设置它们默认为true)。但是我想你做的时候:
let update_lot = defaults.bool(forKey: "update_lot")
...此代码无法知道“unset”应该评估为“true”而不是“false”。您可以改为使用defaults.object(forkey: "update_lot")
,如果返回一个对象,则获取该对象的布尔值(或者只是在该点调用defaults.bool
),但如果它返回nil,则认为它是真的。