How to set Dictionary in NSUserDefault in swift? - swift

I've a mutable dictionary (in form of [Int:Int]) and want that to save it. I would use NSUserDefaults like that:
var myDic: NSMutableDictionary = [:]
myDic = [1:2]
NSUserDefaults.standardUserDefaults().setObject(myDic, forKey: "myDic")
but with that I get an error:
Thread 1: signal SIGABRT
I have no idea why.

setObject(_:forKey:) can’t accept Dictionary with a key which is integer type. The method requires property-list objects, but myDic = [1:2] is not property-list object.
There are two documents about it.
setObject(_:forKey:) of NSUserDefaults
The value parameter can be only property list objects: NSData,
NSString, NSNumber, NSDate, NSArray, or NSDictionary. For
NSArray and NSDictionary objects, their contents must be property
list objects.
About Property Lists
And although NSDictionary and CFDictionary objects allow their keys to
be objects of any type, if the keys are not string objects, the
collections are not property-list objects.
If you set a integer-key to Dictionary, the Dictionary object cannot be used for a value of setObject. You have to use a string for the key like this:
myDic = ["1": 2]

Related

How to directly add a key-value pair to a dictionary with "Cannot assign to immutable expression of type" error?

I have a dictionary that contains a JSON object. I'm trying to directly manipulate that dictionary to add a key-value pair. However, I am getting the Cannot assign to immutable expression of type Any error.
I know that the value of Any is immutable, it cannot be changed. I managed to obtain a reference to it to store it in a different dictionary and applied a key-value pair there, but I like to change the original dictionary to reduce code repetition.
Currently this is the output of the dictionary:
dict = ["Object":
[ ["number_1": -117.13,
"number_2": 32.91,
"link": http://www.google.com]
]
]
What I'm trying to do is the following:
( (dict["Object"] as! [Dictionary<String, Any>])[0] as! Dictionary<String, Any>)["image"] = UIImage(named: "")
I'm trying to add "image" as another key with a UIImage as the value, but I can't due to Any being an immutable type.
How can I directly manipulate dict to add a key-value pair?
FYI: dict is declared as a var, not let

Dictionary saved to NSUserDefaults always returns nil

I'm trying to save a dictionary to NSUserDefaults using the setObject() function but when I use the objectForKey() function to retrieve the dictionary it returns nil. Why is this happening?
var data = NSUserDefaults.standardUserDefaults();
var scoreboard = [Int : String]()
let scores = "scoresKey"
scoreboard[3] = "spencer"
scoreboard[6] = "brooke"
scoreboard[11] = "jason"
data.setObject(scoreboard, forKey: scores)
data.objectForKey(scores) // Returns nil
The first problem was that it's not possible to use NSUserDefaults in a Playground.
See: https://stackoverflow.com/a/31210205/3498950
A second problem is found when the code above runs in a normal iOS project. It throws an NSInvalidArgumentException since the dictionary was a non-property list object because the keys needed to be of type String.
Although NSDictionary and CFDictionary objects allow their keys to be
objects of any type, if the keys are not string objects, the
collections are not property-list objects.
See: "What is a Property List?" in the Apple Docs

How to save [AnyObject!] = [] in NSUserDefaults in Swift?

I need save a variable of type:
var array1: [AnyObject!] = []
I tried this but isn't save:
var key = "keySave"
var defaults = NSUserDefaults.standardUserDefaults()
array1.append(["key1": "val1", "key2": "val2"])
array1.append(["key2": "val3", "key4": "val4"])
defaults.setObject(array1, forKey: key)
defaults.synchronize()
Need I cast this variables to other type of data? What is the correct form to make this?
Thanks!
This is not allowed. According to the documentation of NSUserDefaults class, only these specific types are supported by setObject:forKey: method:
The value parameter can be only property list objects: NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and NSDictionary objects, their contents must be property list objects.
You can fix this by replacing a Swift array with NSMutableArray, a subclass of the allowed NSArray class.

NSDictionary with integer as number

I have a NSDictionary with the following layout:
{
1:{
... some data ...
}
...
}
I have a NSNumber object with a integer value of 1, but when I do
[my_dict objectForKey:my_number] it returns null.
If I try and convert NSNumber to a integer via [my dict objectForKey:[my_number intValue]] I get a warning and the program crashes when it reaches that part of the code.
Any help would be greatly appreciated.
Keys in a NSDictionary or NSMutableDictionary must be objects, like NSNumber. They cannot be primitive data types, like int.
http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/Reference/Reference.html
Looks like you're trying to use an integer as the key in your NSDictionary. This would be correct with an NSArray, with an NSDictionary actually needs a proper object as a key.
You might have more success in this particular case feeding that data into an NSArray, and accessing it with:
id *someData = [my_array objectAtIndex:1];

NSDictionary with key => String and Value => c-Style array

I need an NSDictionary which has key in the form of string (#"key1", #"key2") and value in the form of a C-style two-dimensional array (valueArray1,valueArray2) where valueArray1 is defined as :
int valueArray1[8][3] = { {25,10,65},{50,30,75},{60,45,80},{75,60,10},
{10,70,80},{90,30,80},{20,15,90},{20,20,15} };
And same for valueArray2.
My aim is given an NSString i need to fetch the corresponding two-dimensional array.
I guess using an NSArray, instead of c-style array, will work but then i cannot initialize the arrays as done above (i have many such arrays). If, however, that is doable please let me know how.
Currently the following is giving a warning "Passing argument 1 of 'dictionaryWithObjectsAndKeys:' from incompatible pointer type" :
NSDictionary *myDict = [NSDictionary dictionaryWithObjectsAndKeys:valueArray1,#"key1",
valueArray2,#"key2",nil];
Is valueArray2 also an int[][3]? If so, you could use
[NSValue valueWithPointer:valueArray1]
to convert the array into an ObjC value. To retrieve the content, you need to use
void* valuePtr = [[myDict objectForKey:#"key1"] pointerValue];
int(*valueArr)[3] = valuePtr;
// use valueArr as valueArrayX.
If there's just 2 keys, it is more efficient to use a function like
int(*getMyValueArr(NSString* key))[3] {
if ([key isEqualToString:#"key1"]) return valueArray1;
else return valueArray2;
}
Rather than Adding Array Directly as a value in NSDictionary make a custom class in which create variable of NSArray ... and set this class object as value like
NSDictionary *myDict = [NSDictionary dictionaryWithObjectsAndKeys:MyClassObj1,#"key1",
MyClassObj2,#"key2",nil];
where MyClassObj1 and MyClassObj2 are member of MyClass