patternswiftMinor
Registering a plist to NSUserDefaults
Viewed 0 times
registeringplistnsuserdefaults
Problem
I've been struggling with registering a plist into
My intention with this code:
I want to be able to set all of my values in a plist and essentially use that to "seed" my
My question:
What is the correct way to register a plist into the NSUserDefaults?
I followed the example from this this post and I received compiler errors. So I started experimenting. I could only get the code from the post to work if I added
Once added, it seemed to render the
The lines that I am questioning are these:
I've placed the entirety of the code below to put above lines in context. This is all of the code so you can copy it right into Xcode and it will work.
ViewController.swift
```
class ViewController: UIViewController {
let userDefaults = NSUserDefaults.standardUserDefaults()
override func viewDidLoad() {
super.viewDidLoad()
let prefs = NSBundle.mainBundle().pathForResource("Settings", ofType: "plist")
let dict = NSDictionary(contentsOfFile: prefs!)
userDefaults.setObject(dict, forKey: "defaults") // without this code doesn't work
userDefaults.registerDefaults(dict as! [NSObject : AnyObject]) // with or without this code works... do I need this?
userDefaults.synchronize()
// this just toggles the aBool value
if let defaults = userDefaults.valueForKey("aBool") as? NSNumber {
if defaults as NSObject == 1 {
p
NSUserDefaults and I've finally got it working, though I'm not sure that its written properly. I'm hoping someone here can shine some light on this process. My intention with this code:
I want to be able to set all of my values in a plist and essentially use that to "seed" my
NSUserDefaults. My end goal is to use this as a user settings menu.My question:
What is the correct way to register a plist into the NSUserDefaults?
I followed the example from this this post and I received compiler errors. So I started experimenting. I could only get the code from the post to work if I added
setObject(dict, forKey: "defaults") first.Once added, it seemed to render the
registerDefaults line pointless as the code runs with or without it.The lines that I am questioning are these:
userDefaults.setObject(dict, forKey: "defaults") // without this my code doesn't work
userDefaults.registerDefaults(dict as! [NSObject : AnyObject]) // with or without this code works... do I need this?I've placed the entirety of the code below to put above lines in context. This is all of the code so you can copy it right into Xcode and it will work.
ViewController.swift
```
class ViewController: UIViewController {
let userDefaults = NSUserDefaults.standardUserDefaults()
override func viewDidLoad() {
super.viewDidLoad()
let prefs = NSBundle.mainBundle().pathForResource("Settings", ofType: "plist")
let dict = NSDictionary(contentsOfFile: prefs!)
userDefaults.setObject(dict, forKey: "defaults") // without this code doesn't work
userDefaults.registerDefaults(dict as! [NSObject : AnyObject]) // with or without this code works... do I need this?
userDefaults.synchronize()
// this just toggles the aBool value
if let defaults = userDefaults.valueForKey("aBool") as? NSNumber {
if defaults as NSObject == 1 {
p
Solution
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}If all your method does is call up to the super class's implementation of the method, you can safely omit the method entirely. I understand this is boilerplate code that Xcode automatically inserts any time you create a new view controller, but at the end of the day, it's just clutter that should be cleaned up.
override func viewDidLoad() {
super.viewDidLoad()
let prefs = NSBundle.mainBundle().pathForResource("Settings", ofType: "plist")
let dict = NSDictionary(contentsOfFile: prefs!)
userDefaults.setObject(dict, forKey: "defaults") // without this code doesn't work
userDefaults.registerDefaults(dict as! [NSObject : AnyObject]) // with or without this code works... do I need this?
userDefaults.synchronize()
// this just toggles the aBool value
if let defaults = userDefaults.valueForKey("aBool") as? NSNumber {
if defaults as NSObject == 1 {
println("inside the conditional: \(defaults)")
userDefaults.setValue(0, forKey: "aBool")
userDefaults.synchronize()
println("Setting aBool to true")
} else {
userDefaults.setValue(1, forKey: "aBool")
userDefaults.synchronize()
println("setting aBool to false")
}
}
}I don't want to say this is objectively too much code for
viewDidLoad, but it's not appropriate for this to all go in viewDidLoad. This really doesn't belong in the viewDidLoad of any view controller, really. This is code we seem to only want to load once. This really belongs in our app delegate, in application(_:didFinishLaunchingWithOptions:).Once we get our list loaded into
NSUserDefaults, we just need to access the values through NSUserDefaults, which is a singleton we can easily access from anywhere.As a final note about all of this, calling
synchronize is generally going to be unnecessary. NSUserDefaults will synchronize itself when it finds a convenient time. Moreover, all synchronize does is synchronize what NSUserDefaults has stored in memory with what it has stored in long-term storage. The only time you can lose something that you put in NSUserDefaults is if your app crashes after you changed a value and before NSUserDefaults had a chance to synchronize. This is extraordinarily rare. And for emphasis, realize that I said this happens when your app crashes. If the user exits your app, NSUserDefaults will synchronize before the app is allowed to completely exit.And when you access the values in
NSUserDefaults, you'll get the value it was most recently set to (which isn't necessarily what is saved to the permanent storage at that moment).Calling
synchronize just forces the synchronization to happen at that very instant, which is entirely unnecessary.And, for the record, our inner most conditional can be simplified:
if let defaults = userDefaults.valueForKey("aBool") as? NSNumber {
userDefaults.setValue(!defaults.boolValue, forKey: "aBool")
}Code Snippets
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}override func viewDidLoad() {
super.viewDidLoad()
let prefs = NSBundle.mainBundle().pathForResource("Settings", ofType: "plist")
let dict = NSDictionary(contentsOfFile: prefs!)
userDefaults.setObject(dict, forKey: "defaults") // without this code doesn't work
userDefaults.registerDefaults(dict as! [NSObject : AnyObject]) // with or without this code works... do I need this?
userDefaults.synchronize()
// this just toggles the aBool value
if let defaults = userDefaults.valueForKey("aBool") as? NSNumber {
if defaults as NSObject == 1 {
println("inside the conditional: \(defaults)")
userDefaults.setValue(0, forKey: "aBool")
userDefaults.synchronize()
println("Setting aBool to true")
} else {
userDefaults.setValue(1, forKey: "aBool")
userDefaults.synchronize()
println("setting aBool to false")
}
}
}if let defaults = userDefaults.valueForKey("aBool") as? NSNumber {
userDefaults.setValue(!defaults.boolValue, forKey: "aBool")
}Context
StackExchange Code Review Q#87260, answer score: 5
Revisions (0)
No revisions yet.