NSDictionary valueForKey crash - ios

How can i retrieve the key value from the below NSMutableArray array. The below code crashes on isEqualToString. However i can see the value of nsRet in the variable view window as #\x18\xaa\x01\xc8\a before running that statement.
NSMutableArray* nsMyList = [[NSMutableArray alloc] init];
[nsMyList addObject:[NSDictionary dictionaryWithObjectsAndKeys:
#"valueOfKey", #"Key",
nil]];
NSString *nsRet = [nsMyList valueForKey:#"Key"];
if ([nsRet isEqualToString:#"deviceClass"])
{
NSLog(#"Key value:%#", nsRet);
}
Can anyone here please help me get the correct value for the key?
Thanks.

This is because you need objectForKey:, not valueForKey:. The valueForKey: method is for key-value programming. Moreover, the call should be on the [nsMyList objectAtIndex:0], like this:
NSString *nsRet = [[nsMyList objectAtIndex:0] objectForKey:#"Key"]

You've stored the NSDictionary in an array. The correct access based on your code would be:
NSDictionary *dict = [nsMyList objectAtIndex:0];
nsret = [dict valueForKey:#"Key"];

It looks like you are trying to get the valueForKey: on an NSMutableArray rather than on the dictionary.
What you want is:
[[nsMyList objectAtIndex:0] valueForKey:#"Key"];

I am a bit lost.
In order to access the dictionary you just create you need to obtain the first element in the NSMutableArray and then the dictionary.
It will be something like this:
NSString *nsRet = [nsMyList[0] objectForKey:#"Key"]
I think it can solve it.

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

NSDictionary allKeysForObject in an array

I have a NSDictonary that looks like this. I need to get all the key values that are associated for a particular name. For example the name Samrin is associated with keys 11.titleKey, 110.titleKey and so on. The problem I have is that I am not sure how can I get to the object in an array and then pass they key value back?
I tried the following code with not much success.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"birthdays.plist"];
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:stringsPlistPath];
NSArray *temp = [dictionary allKeysForObject:#"Samrin Ateequi"];
NSLog(#"temp: %# ...", temp);
OUTPUT:
temp: (
) ...
I think you can use keysOfEntriesPassingTest for that. Something like:
NSSet *keysSet = [dictionary keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop) {
if ([[obj objectAtIndex:0] isEqualToString:#"Samrin Ateequi"]) {
return YES;
} else {
return NO;
}
}];
allKeysForObject: looks through the dictionary for values equal to that object using isEqual:. Your values for that dictionary are NSArrays, so it will never match the NSString you are looking for.
If you don't change the data structure you will have to loop through everything to get the results you need.
If you are willing to upgrade to Core Data with an SQL store, then your results will be fast and the code will be easier than looping through the dictionary. This is the kind of problem that Core Data was meant to solve. You can get started with the Core Data Programming Guide.
Hope this will help you: I have taken an example.
NSDictionary *dict = #{#"key1":#[#"mania",#"champ"],
#"key2":#[#"mann",#"champ"],
#"key3":#[#"mania",#"champ",#"temp"]};
NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:#"ANY SELF=%#",#"mania"];
NSArray *allValues = [dict allValues];
NSArray *requiredRows = [allValues filteredArrayUsingPredicate:filterPredicate];
NSMutableArray *requiredKeyArray = [[NSMutableArray alloc]initWithCapacity:0];
for (id anObj in requiredRows) {
[requiredKeyArray addObject:[dict allKeysForObject:anObj]];
}
NSLog(#"Desc: %#",[requiredKeyArray description]);

Add other object to NSArray

I made a small code
NSArray* _options = [NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:[UIImage imageNamed:#"2"],#"img",name,#"text"
, nil],nil];
Now, I want add other object to _options. What should i do?
I make more test but no success.
Thank for all
you can use [NSArray arrayByAddingObject:]
_options = [_options arrayByAddingObject:object];
or change _options to NSMutableArray
NSMutableArray *_options = [NSMutableArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:[UIImage imageNamed:#"2"],#"img",name,#"text"
, nil],nil];
[_options addObject:object];
and you may want to use modern syntax
NSMutableArray *_options = [#[#{#"img":[UIImage imageNamed:#"2"],#"text":name}] mutableCopy];
[_options addObject:object];
NSArray does not allow any changes to be made; you can use an NSMutableArray instead like this:
NSMutableArray *mutable = [_options mutableCopy];
[mutable addObject:yourObject];
NSDictionary is same in that it can't be mutated.
You can't add objects to a NSArray, to do so, you need a NSMutableArray.
However, you can add objects to NSArray when creating it with : arrayWithObjects
First, create an NSMutableArray, as you can make changes to it as you see fit later throughout your code:
NSMutableArray *newOptions = [NSMutableArray alloc]init];
[newOptions setArray:_options];
[newOptions addObject:yourObject];

NSDictionary from NSArray using KVC

Is it possible to get an NSDictionary using KVC from a NSArray of CALayer based on key property name? I tried using -dictionaryWithValuesForKeys:, but that returns an NSArray.
Any idea?
NSArray *tempArray = [self.layer.sublayers copy];
NSArray *ListName = [self.layer.sublayers valueForKey:#"name"];
NSDictionary *tmpD= [tempArray dictionaryWithValuesForKeys:ListName];
Thanks
Is this what you're asking about?
NSDictionary * layersByName = [NSDictionary dictionaryWithObjects:[self.layer.sublayers copy]
forKeys:[self.layer.sublayers valueForKey:#"name"]];
-[NSArray valueForKey:] returns an array formed by asking each object in the reciever for its own valueForKey:, using the same argument.
I don’t know of a way to do this directly with KVC. It’s pretty simple to do just by iterating over the array, though:
NSMutableDictionary *layersByName = [NSMutableDictionary dictionary];
for (CALayer *layer in self.layer.sublayers)
{
[layersByName setObject:layer forKey:layer.name];
}

Sorting the Key/Values stored in NSArray

I have a
NSDictionary* dict = [[NSDictionary alloc]initWithObjectsAndKeys::arrayOne,#"Plants",arrayTwo,#"Animals"),arrayThree,#"Birds",nil];`
self.displayArray =[[dict allKeys] sortedArrayUsingSelector:#selector(compare:)];
Everything works fine, I am able to see all the key value/pair in the table but they are in sorted order. i.e Animals,Birds,Plants.
But I want to display as Plants,Animals,Birds.
Can anyone tell me how to sort the array in my customized order?
I have googled and found that we can use NSSortDescriptor for sorting. But I am not very clear with that. Can anyone help me ?
As your ordering doesnt follow any natural order, a simple solution could be to keep track of the order with another array
NSArray *array1 = [NSArray arrayWithObjects:#"rose",#"orchid",#"sunflower",nil];
NSArray *array2 = [NSArray arrayWithObjects:#"dog", #"cat",#"ogre",#"wookie", nil];
NSArray *array3 = [NSArray arrayWithObjects:#"parrot",#"canary bird",#"tweety",#"bibo",nil];
NSArray *keys = [NSArray arrayWithObjects:#"Plants",#"Animals",#"Birds", nil];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
array1,[keys objectAtIndex:0],
array2,[keys objectAtIndex:1],
array3,[keys objectAtIndex:2],
nil];
for (NSString *key in keys) {
NSLog(#"%# %#", key, [dict objectForKey:key]);
}
Matt shows in his fantastic blog, how to create a ordered dictionary, that essentially uses another array to keep the order just as I showed here: OrderedDictionary: Subclassing a Cocoa class cluster
You're on the right track, Cyril.
Here is some Apple documentation on "Creating and using Sort Descriptors"
Basically you need to subclass NSSortDescriptor and in your subclass, implement your own "compare:" method (you can actually name it anything you want; it needs to return a "NSComparisonResult") that somehow logically returns "Plants" before "Animals".

Resources