Store and update a Swift Dictionary in NSUserDefaults


#1

Hello,
I would like to store and update a Dictionary when a user enters a value. Everything seems to function until this code, and the application crashes:

override func viewDidLoad() {
super.viewDidLoad()

if NSUserDefaults.standardUserDefaults().objectForKey("answersSaved") != nil  {
    answersSaved = NSUserDefaults.standardUserDefaults().objectForKey("answersSaved") as [String:String]
}

}
The error message says "anyObject is not convertible to [String:String]. It offers to add ! after the as but then the app crashes.

answersSaved is my Dictionary variable with Strings as values.

I also have code updating the NSUserDefaults but it appears to be functioning.

Thanks so much in advance!


#2

Try using only NSString instead of String when using NSUserDefaults…


#3

Unfortunately the build failed, it didn’t work. Any other suggestions? Thanks!


#4

Can you upload to GitHub or provide some more info ?


#5

This is how I update the NSUserDefaults:

NSUserDefaults.standardUserDefaults().setObject(“answersSaved”, forKey: “answersSaved”)

The message when the app crashes is Thread 1 Signal SIGABRT

Hope this is enough. Thanks for helping!


#6

Hm…SIGABRT errors are usually related to mistakes in the Story Board, check your outlets. Check UILABELS, UIBUTTONS and such, most likely you dragged from a Story Board item, then deleted the code, but the connection is still inside the SB item.


#7

Just checked and replaced all outlets and actions…still same error. What else could it be?


#8

Can you take a picture of the error or upload your project somewhere ?


#11

Ok, so I’ve been working on this and now I get that my NSDictionary has been converted to a NSCFString when saved to NSUserDefaults. What is this, why is it happening and what can I do about it?

Thanks a lot for any help!


#12

I don’t think that’s your problem.
Not 100% sure, but these are ‘toll-free-bridged’ ( https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/CocoaEncyclopedia/Toll-FreeBridgin/Toll-FreeBridgin.html#//apple_ref/doc/uid/TP40010810-CH2)
so they can be used interchangeably.
Apple have their own separation of public and private interface classes…

You can look at this snippet from Apple:

CFString is “toll-free bridged” with its Cocoa Foundation counterpart, NSString. This means that the Core Foundation type is interchangeable in function or method calls with the bridged Foundation object. Therefore, in a method where you see an NSString * parameter, you can pass in a CFStringRef, and in a function where you see a CFStringRef parameter, you can pass in an NSString instance. This also applies to concrete subclasses of NSString. See Toll-Free Bridged Types for more information on toll-free bridging.


#13

Best way to get help, in case it’s not a project you are trying to sell on the app store, is to upload the whole project on GitHub or something similar.


#14

Thanks, I solved the problem!


#15

Great. What did it turn out to be ?


#16

When I was unwrapping it, apparently it was automatically being made into a NSCF string. When I unwrapped it with let, it worked fine. It’s odd that you have to do that though.


#17

Hmmm, might have been a problem with nil values. I know the NSUserDefaults it’s a bit weird on adding and removing values, as they still stay there, but become nil. So you always have to use ‘if let’. Per Apple’s docs NSCF and NS Strings should be able to be used interchangeably.Might be a bug, if that’s not true…