Initialize NSMutableDictionary - ios

I am developing an iOS application in which I want to use an NSMutableDictionary. Basically what I am doing is converting java code to objectiveC.
So in java I have something like this:
Map<String, ClassA> dict1 = new HashMap<>();
Map<Integer,Character> dict2 = new HashMap<>();
Map<Integer, Map<String,String>> dict3 = new HashMap<>();
Can someone please guide me as what would be the Obj-C equivalent code for the above three lines using NSMutableDictionary and also how can I set and get the pairs in/from the dictionaries.

The Objective-C collection classes are not strongly typed so all three dictionaries would be created using:
NSMutableDictionary *dictX = [NSMutableDictionary new];
In order to populate the dictionary use [NSMutableDictionary setObject:forKey:]:
[dict1 setObject:classAInstance
forKey:#"key1"];
[dict2 setObject:[NSString stringWithFormat:#"%c", character]
forKey:#(1)];
[dict3 setObject:#{ #"innerKey" : #"innerValue" }
forKey:#(2)];
etc.

Since Objective C does not have generic types all you have to type is this:
NSMutableDictionary *dict1 = [[NSMutableDictionary alloc] init];
NSMutableDictionary *dict2 = [[NSMutableDictionary alloc] init];
NSMutableDictionary *dict3 = [[NSMutableDictionary alloc] init];
There's a couple ways to get and set values. The shorthand form is much like accessing arrays.
To set a value with shorthand:
dict1[#"key"] = #"value";
To get a value with shorthand:
NSString *value = dict1[#"key"];
More verbose syntax is like so:
[dict1 setObject:#"value" forKey:#"key"];
NSString *value = [dict1 valueForKey:#"key"];

Related

Combining dictionaries: No class method for selector "addEntriesFromDictionary"

I am struggling with a dictionary in which I want to create a new dictionary from a series of keys (P, SP, and RP).
I have attempted to create a new NSMutableDictionary that combines individual Dictionaries that have have all the values for the P, SP, and RP keys respectively, but have gotten the error "No class method for selector "addEntriesFromDictionary" "
Here is my code:
NSMutableDictionary *newDict = [NSMutableDictionary addEntriesFromDictionary:self.allSPPositions];
and
#interface className ()
- (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;
#end
#implementation className
- (void)viewDidLoad {
Any help or insight would be appreciated! Thanks!
The compiler is telling you exactly what's wrong. You're trying to add items from a dictionary to the NSMutableDictionary class. You need to send the ad items from dictionary message to an instance of NSMutableDictionary.
This line:
NSMutableDictionary *newDict =
[NSMutableDictionary addEntriesFromDictionary:self.allSPPositions];
Should read
NSMutableDictionary *newDict =
[someDictionary addEntriesFromDictionary: self.allSPPositions];
(Where someDictionary is the dictionary to which you want to add items.)
or even
NSUInteger count = [self.allSPPositions count];
NSMutableDictionary *newDict =
[NSMutableDictionary dictonaryWithCapacity: count];
[newDict addEntriesFromDictionary: self.allSPPositions];
(Since your code appears to be trying to create a new, mutable dictionary and add the contents of self.allSPPositions.)
If your goal is to get a mutable copy of self.allSPPositions, there is a cleaner way to do that:
NSMutableDictionary *mutablePositions = [self.allSPPositions mutableCopy];
Uhh, here's an example that will compile and use the method in question, you should probably NOT call that method in your Interface since it's part of Apple's framework and is already predefined, unless you have a special reason for doing so:
NSMutableDictionary *dict =[[NSMutableDictionary alloc] init];
[dict setValue:#"Seattle" forKey:#"name"];
[dict setObject:[NSNumber numberWithInt:3] forKey:#"age"];
[dict setObject:[NSDate date] forKey:#"date"];
dict[#"city"]=#"Seattle";
[dict addEntriesFromDictionary:[NSMutableDictionary dictionaryWithObjectsAndKeys: #"Washington",#"location", nil]];
This is merely meant to get you started, but it shows you how to do this so that it works for you in your circumstances

How to change a value inside a nested NSDictionary?

I have a textfield dynamically generated and it is added in to an mutable array named field:
[field addObject:textfield];
textfield contains all the properties of the textfield (like placeholder etc...).
Now I have a mutable dictionary with a key-value pair like this:
NSMutableDictionary *m = [[NSMutableDictionary alloc] init];
[m setObject:#{} forKey:#"V"];
Now what I want to achieve is that I want to change the value of m.V[field[i].placeholder] with the value #"abc". It is inside a for loop.
What I want is that to add a value corresponding to field[i].placeholder key.
I dont know how to write the above code.
Can anyone please help? I hope the question is clear.
EDIT:
for(UITextField *f in field){
[[m objectforkey:#"V"] setobject:#"abc" forkey:#"placeholder"];
}
This is what i am trying to achieve.But it shows error.
I suspect the issue is that the inner dictionary is immutable as you have used the newer Objective-C literal syntax. Instead, create the dictionary with the following code, which explicitly creates an inner mutable dictionary:
NSMutableDictionary *m = [[NSMutableDictionary alloc] init];
NSMutableDictionary *inner = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"value1", #"key1",
#"value2", #"key2",
nil];
[m setObject:inner forKey:#"V"];
Your question is not clear, but I guess this is the answer for your question.
for (UITextField *textfield in [m valueForKey: #"V"]){
textField.placeholder = #"abc";
}

How to create object in IOS similar to JAVASCRIPT

How can i create an object which is similar in javascript?
var writers = {
publicAccess: false,
ids: []
};
Please help ?
Use an NSDictionary.
The quickest way to create this is the following:
NSDictionary *dict = #{ #"publicAccess": #NO,
#"ids": #[#"id1", #"id2"] };
With the full Objective-C syntax, and if you don't want a static dictionary, it could go:
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:#NO forKey:#"publicAccess"];
[dict setObject:[[NSMutableArray alloc] initWithObjects:#"id1", #"id2", nil] forKey:#"ids"];

Trying add NSMutableDictionary to NSMutableArray

I am very new to Objective-C and iOS programming so be gentle :)
I am trying to add an nsmutabledictionary to and nsmutablearray. I am succeeding but not with the results I was hoping for. Here is my code :
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
NSMutableDictionary *messages = [[NSMutableDictionary alloc] init];
NSMutableArray *array = [[NSMutableArray alloc] init];
[dictionary setValue:#"lat1" forKey:#"lat"];
[dictionary setValue:#"long1" forKey:#"long"];
[dictionary setValue:#"alt1" forKey:#"alt"];
[messages setObject:dictionary forKey:#"messages"];
[array addObject:messages];
[dictionary setValue:#"lat2" forKey:#"lat"];
[dictionary setValue:#"long2" forKey:#"long"];
[dictionary setValue:#"alt2" forKey:#"alt"];
[messages setObject:dictionary forKey:#"messages"];
[array addObject:messages];
NSLog(#"%#",array);
NSLog(#"%lu",(unsigned long)[array count]);
Here is the NSLog output:
2014-06-05 10:29:27.377 dicttest[4863:60b] (
{
messages = {
alt = alt2;
lat = lat2;
long = long2;
};
},
{
messages = {
alt = alt2;
lat = lat2;
long = long2;
};
}
)
2014-06-05 10:29:27.386 dicttest[4863:60b] 2
Here is what I was hoping to achieve:
2014-06-05 10:29:27.377 dicttest[4863:60b] (
{
messages = {
alt = alt1;
lat = lat1;
long = long1;
};
},
{
messages = {
alt = alt2;
lat = lat2;
long = long2;
};
}
)
2014-06-05 10:29:27.386 dicttest[4863:60b] 2
If I the dictionary straight to the array (instead of add the dictionary to messages and then adding that to the array) then I get the output I am looking for. Can somebody explain to me exactly what I am doing wrong?
It looks to me like you want:
An array
At index 0:
A dictionary with a single key "messages"
A dictionary with keys "alt", "lat", and "long"
At index 1:
A dictionary with a single key "messages"
A dictionary with keys "alt", "lat", and "long"
The data in the second array entry should use the same keys, but different data. As the others have pointed out, your mistake is using a single dictionary "dictionary"
When you add an object to a collection like a dictionary or array, the collection holds a pointer to the object, not a copy of the object. If you add the same object to a collection more than once, you have 2 pointers to the same object, not 2 unique objects.
When you add your "dictionary" object, to your structure, change it, and add it again, you are not getting the result you expect because both entries in your structure point to a single dictionary. When you change the values, it changes in both places.
The same goes for your "messages" dictionary. You need 2 of those as well.
Fix your code by adding new dictionaries, dictionary2 and messages2:
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
NSMutableDictionary *dictionary2 = [[NSMutableDictionary alloc] init];
NSMutableDictionary *messages = [[NSMutableDictionary alloc] init];
NSMutableDictionary *messages2 = [[NSMutableDictionary alloc] init];
NSMutableArray *array = [[NSMutableArray alloc] init];
[dictionary setValue:#"lat1" forKey:#"lat"];
[dictionary setValue:#"long1" forKey:#"long"];
[dictionary setValue:#"alt1" forKey:#"alt"];
[messages setObject:dictionary forKey:#"messages"];
[array addObject:messages];
[dictionary2 setValue:#"lat2" forKey:#"lat"];
[dictionary2 setValue:#"long2" forKey:#"long"];
[dictionary2 setValue:#"alt2" forKey:#"alt"];
[messages2 setObject: dictionary2 forKey:#"messages"];
[array addObject: messages2];
NSLog(#"%#",array);
NSLog(#"%lu",(unsigned long)[array count]);
You might also look at using object literal syntax, e.g.:
dictionary[#"lat"] = #"lat1";
dictionary[#"long"] = #"long1";
dictionary[#"alt"] = #"alt1";
messages[#"messages"] = dictionary;
If you didn't need the whole thing to be mutable, you could even do everything with one line:
NSMutableArray *array = [
#[
#{#"messages": #{#"lat": #"lat1", #"long": #"long1", #"alt": #"alt1"}},
#{#"messages": #{#"lat": #"lat2", #"long": #"long2", #"alt": #"alt2"}}
];
Or to make it mutable:
NSMutableArray *array = [
#[
[#{#"messages":
[#{#"lat": #"lat1", #"long": #"long1", #"alt": #"alt1"} mutableCopy]} mutableCopy],
[#{#"messages":
[#{#"lat": #"lat2", #"long": #"long2", #"alt": #"alt2"} mutableCopy]} mutableCopy]
] mutableCopy];
EDIT: to add contents dynamically, you could use a method like this: (assuming that array is an instance variable)
- (void) addMessageWithLat: (NSString *) latString
long: (NSString *) longString
alt: (NSString *) altString;
{
NSMutableDictionary *messages = [[NSMutableDictionary alloc] init];
NSDictonary *contents =
[#{#"lat": latString,
#"long": longString,
#"alt": altString}
mutableCopy];
messages[#"messages"] = contents;
[array addObject: messages];
}
The problem is that you are making adding the new values in the same object reference. So the new Value will replace the older one. Just add this line before [dictionary setValue:#"lat2" forKey:#"lat"];
dictionary = [NSMutableDictionary alloc]init];
and this line before the second instance of [messages setObject:dictionary forKey:#"messages"];
messages = [[NSMutableDictionary alloc] init];

NSString containing just # ist not Key Value Compliant

Why is a NSString #"#" not Key Value Compliant?
Are there other strings that aren't compliant as well?
You can try that it is failing with this code for example:
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:#"Some Object" forKey:#"#"];
NSString *theObject = [dict valueForKey:#"#"];
Setting it as a key is ok but not querying for that key..
Sure you can work around this error by appending some other string you later on remove another time like doing the following when you want to have the key #:
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:#"Some Object" forKey:#"keyConst#"];
NSString *theObject = [dict valueForKey:#"keyConst#"];
The counterpart to setObject:forKey: is
objectForKey: (and not valueForKey:) to retrieve an item from a dictionary:
NSString *theObject = [dict objectForKey:#"#"];
Alternatively, use the "new" dictionary subscripting syntax:
dict[#"#"] = #"Some Object";
NSString *theObject = dict[#"#"];
valueForKey: uses Key-Value coding methods if the key starts with #.
From the documentation of -[NSDictionary valueForKey:]:
If key does not start with “#”, invokes objectForKey:. If key does
start with “#”, strips the “#” and invokes [super valueForKey:] with
the rest of the key.
For example,
NSString *x = [dict valueForKey:#"#description"];
does the same as
NSString *x = [dict description];
So in almost all cases, you should use objectForKey:, unless you explicitly
want to do some Key-Value coding magic.

Resources