Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift NSUserDefaults not saving Dictionary?

Tags:

I have the following test code:

  func testSaveDictionary() {     let userDefaults = NSUserDefaults.standardUserDefaults()     var jo = [       "a" : "1.0",       "b" : "2.0"     ]      let akey = "aKey"     userDefaults.setObject(jo, forKey: akey)     var isOk = userDefaults.synchronize()      var data0 = userDefaults.dictionaryForKey(akey)     println(data0)    } 

The output of println(data0) is nil.

Anything wrong with my code? Is Swift Dictionary considered property list now or in the final release?

like image 645
Sean Avatar asked Sep 09 '14 19:09

Sean


People also ask

How do I save a dictionary in Swift?

We access the shared defaults object through the standard class property of the UserDefaults class. We then create a dictionary of type [String:String] and store the dictionary in the user's defaults database by invoking the set(_:forKey:) method of the UserDefaults database.

Can we save a dictionary in UserDefaults?

This system, called UserDefaults can save integers, booleans, strings, arrays, dictionaries, dates and more, but you should be careful not to save too much data because it will slow the launch of your app.

How do you save a string in UserDefaults?

To store the string in the user's defaults database, which is nothing more than a property list or plist, we pass the string to the set(_:forKey:) method of the UserDefaults class. We also need to pass a key as the second argument to the set(_:forKey:) method because we are creating a key-value pair.


Video Answer


2 Answers

Update for Swift 2, Xcode 7: As @atxe noticed, NSUserDefaults dictionaries are now mapped as [String, AnyObject]. This is a consequence of the Objective-C "lightweight generics" which allow to declare the Objective-C method as

- (NSDictionary<NSString *,id> *)dictionaryForKey:(NSString *)defaultName 

(Default objects must be property lists and in particular the dictionary keys can only be strings.)

On the other hand, a Swift dictionary is bridged automatically if possible, so the original code from the question works (again):

let jo = [     "a" : "1.0",     "b" : "2.0" ]  let akey = "aKey" // Swift 2: userDefaults.setObject(jo, forKey: akey) // Swift 3: userDefaults.set(jo, forKey: akey) 

Original answer for Swift 1.2: The user defaults can store NSDictionary objects. These are mapped to Swift as [NSObject : AnyObject]:

var jo : [NSObject : AnyObject] = [     "a" : "1.0",     "b" : "2.0" ]  userDefaults.setObject(jo, forKey: akey) var isOk = userDefaults.synchronize() 

And note that dictionaryForKey() returns an optional, so you should check it for example with an optional assignment:

if let data0 = userDefaults.dictionaryForKey(akey) {     print(data0) } else {     print("not set") }  // Output: [b: 2.0, a: 1.0] 
like image 149
Martin R Avatar answered Sep 21 '22 05:09

Martin R


You need to convert it into NSData first. Something like this:

var data = NSKeyedArchiver.archivedDataWithRootObject(jo) var userDefaults = NSUserDefaults.standardUserDefaults() userDefaults.setObject(data, forKey:akey)  
like image 24
Anthony Kong Avatar answered Sep 20 '22 05:09

Anthony Kong