我创建了一个项目,用于设置和检索 settings.bundle 中的值。我还在 settings.bundle 文件中设置了一些默认值。现在问题是我将值检索为
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
loginName.text = [defaults objectForKey:@"login_name"];
第一次显示null,但是在iPhone应用程序设置中设置了值。 如果我更改值或手动设置它,则可以正确检索值。
帮帮我
答案 0 :(得分:36)
虽然您定义了默认设置,但它们并未真正存储为值。它们默认存储。如果您尝试读取它,则该值为null。默认设置是值为的另一个属性。但这并不意味着将默认值写为默认值。
我所做的是,首先,检查一些设置(我确定应该有一个值)是否存在任何设置。如果它没有任何东西,那么我写下所有的默认值。
这是一个例子。
在AppDelegate.m上我检查 email_notificaciones_preference 是否有值,如果没有,我会将所有默认设置写入每个设置。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
NSUserDefaults * standardUserDefaults = [NSUserDefaults standardUserDefaults];
NSString * email_notificaciones_preference = [standardUserDefaults objectForKey:@"email_notificaciones_preference"];
if (!email_notificaciones_preference) {
[self registerDefaultsFromSettingsBundle];
}
}
这个函数是我用来为每个元素写默认值的。
#pragma NSUserDefaults
- (void)registerDefaultsFromSettingsBundle {
// this function writes default settings as settings
NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
if(!settingsBundle) {
NSLog(@"Could not find Settings.bundle");
return;
}
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]];
NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"];
NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];
for(NSDictionary *prefSpecification in preferences) {
NSString *key = [prefSpecification objectForKey:@"Key"];
if(key) {
[defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key];
NSLog(@"writing as default %@ to the key %@",[prefSpecification objectForKey:@"DefaultValue"],key);
}
}
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister];
}
希望有所帮助。
答案 1 :(得分:5)
如果有人需要它 - 我将MIQUEL的答案翻译成Swift(尽我所能,因为我还在学习):
var standardUserDefaults = NSUserDefaults.standardUserDefaults()
var us: AnyObject? = standardUserDefaults.objectForKey("your_preference")
if us==nil {
self.registerDefaultsFromSettingsBundle();
}
func registerDefaultsFromSettingsBundle:
func registerDefaultsFromSettingsBundle() {
// this function writes default settings as settings
var settingsBundle = NSBundle.mainBundle().pathForResource("Settings", ofType: "bundle")
if settingsBundle == nil {
NSLog("Could not find Settings.bundle");
return
}
var settings = NSDictionary(contentsOfFile:settingsBundle!.stringByAppendingPathComponent("Root.plist"))!
var preferences: [NSDictionary] = settings.objectForKey("PreferenceSpecifiers") as [NSDictionary];
var defaultsToRegister = NSMutableDictionary(capacity:(preferences.count));
for prefSpecification:NSDictionary in preferences {
var key: NSCopying? = prefSpecification.objectForKey("Key") as NSCopying?
if key != nil {
defaultsToRegister.setObject(prefSpecification.objectForKey("DefaultValue")!, forKey: key!)
}
}
NSUserDefaults.standardUserDefaults().registerDefaults(defaultsToRegister);
}
答案 2 :(得分:3)
swift 2.1的更新版本:
func registerDefaultsFromSettingsBundle() {
let userDefaults = NSUserDefaults.standardUserDefaults()
if let settingsURL = NSBundle.mainBundle().URLForResource("Root", withExtension: "plist", subdirectory: "Settings.bundle"),
settings = NSDictionary(contentsOfURL: settingsURL),
preferences = settings["PreferenceSpecifiers"] as? [NSDictionary] {
var defaultsToRegister = [String: AnyObject]()
for prefSpecification in preferences {
if let key = prefSpecification["Key"] as? String,
value = prefSpecification["DefaultValue"] {
defaultsToRegister[key] = value
NSLog("registerDefaultsFromSettingsBundle: (\(key), \(value)) \(value.dynamicType)")
}
}
userDefaults.registerDefaults(defaultsToRegister);
} else {
NSLog("registerDefaultsFromSettingsBundle: Could not find Settings.bundle");
}
}
答案 3 :(得分:2)
针对Swift 3进行了更新:
func registerDefaultsFromSettingsBundle() {
let userDefaults = UserDefaults.standard
if let settingsURL = Bundle.main.url(forResource: "Root", withExtension: "plist", subdirectory: "Settings.bundle"),
let settings = NSDictionary(contentsOf: settingsURL),
let preferences = settings["PreferenceSpecifiers"] as? [NSDictionary] {
var defaultsToRegister = [String: AnyObject]()
for prefSpecification in preferences {
if let key = prefSpecification["Key"] as? String,
let value = prefSpecification["DefaultValue"] {
defaultsToRegister[key] = value as AnyObject
debugPrint("registerDefaultsFromSettingsBundle: (\(key), \(value)) \(type(of: value))")
}
}
userDefaults.register(defaults: defaultsToRegister)
} else {
debugPrint("registerDefaultsFromSettingsBundle: Could not find Settings.bundle")
}
}
答案 4 :(得分:0)
试试这个
注册设置包的默认值
NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:defaultValue forKey:@"key"];
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
在检索设置包之前,值会同步数据
[[NSUserDefaults standardUserDefaults] synchronize]
答案 5 :(得分:0)
您可以使用一个简单的属性包装器,如下所示:
@SettingsBundleStorage(key: "storageUsage_preference")
var storageUsage: Double
请注意,只需在变量前添加@objc
,即可100%与Objective-c兼容。
设置捆绑包值位于UserDefaults
中,因此您可以为其使用自定义PropertyWrapper
。以下包装器适用于任何UserDefault
值,包括SettingsBundle
的所有值。
@propertyWrapper
public struct SettingsBundleStorage<T> {
private let key: String
public init(key: String) {
self.key = key
setBundleDefaults(plist: .root) // This is the main plist
setBundleDefaults(plist: .child(name: "DeveloperOptions")) // This is an example child.
}
public var wrappedValue: T {
get { UserDefaults.standard.value(forKey: key) as! T }
set { UserDefaults.standard.set(newValue, forKey: key) }
}
}
您应为根plist
和子extension SettingsBundleStorage {
enum PList {
case root
case child(name: String)
var name: String {
var file: String
switch self {
case .root: file = "Root"
case .child(let name): file = name.replacingOccurrences(of: ".plist", with: "")
}
file.append(".plist")
return file
}
}
}
传递以下枚举:
extension SettingsBundleStorage {
func setBundleDefaults(plist: PList = .root) {
let settingsName = "Settings"
let settingsExtension = "bundle"
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(plist.name)),
let settingsPlist = try? PropertyListSerialization.propertyList(
from: settingsData,
options: [],
format: nil) as? [String: Any],
let settingsPreferences = settingsPlist?[settingsPreferencesItems] as? [[String: Any]] else {
return assertionFailure("Can not get the \(plist.name) from the bundle: \(settingsName)")
}
var defaultsToRegister = [String: Any]()
settingsPreferences.forEach { preference in
if let key = preference[settingsPreferenceKey] as? String {
defaultsToRegister[key] = preference[settingsPreferenceDefaultValue]
}
}
UserDefaults.standard.register(defaults: defaultsToRegister)
}
}
此包装器使用以下功能查找捆绑密钥的默认值:
import pymc3
此包装器可以将任何一种可编码的代码存储到用户默认值中/从用户默认值中恢复,包括所有已经符合该编码的Swift标准数据类型。
此外,您可以找到类似的代码,但是使用较少的代码版本可以从任何用户默认值访问任何键值,您可以查看this answer here