How to get count of objects in NSArray inside of NSDictionary - ios

I need to get a count of the objects in array inside of NSDictionary. For example:
po _dictionary
{
keys = (
"one",
"two"
);
}
Taking in consideration this is an array : [_dictionary objectForKey:#"keys"]
my question is how can I get the count in the array?
I try this :
[[[_tutorials objectForKey:#"keys"] allKeys ]count];
but I'm getting this error:
* Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[__NSCFArray allKeys]:
unrecognized selector sent to instance 0xa419ea0'

[_dictionary objectForKey:#"keys"] is an NSArray and not an NSDictionary. Therefore, it doesn't understand the allKeys method. Drop it and it should work:
[[_dictionary objectForKey:#"keys"] count];

Here you go:
NSLog(#"%lu", _dictionary[#"keys"].count);

NSDictionary has a method to get a NSArray of keys which I find is much more readable than using objectForKey:
[[_dictionary allKeys] count]

NSLog(#"%d", [[_dictionary objectForKey:#"keys"] count]);
As your [_dictionary objectForKey:#"keys"] is an array you can get the count directly.

NSDictionary *res=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error1];
NSLog(#"%d",[[res valueForKey:#"result"] count]);

Related

-[__NSArrayM objectForKey:]: unrecognized selector sent to instance 0x9d0d720

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[jsonArray removeAllObjects];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
responseData = nil;
NSMutableArray *sdf = [(NSDictionary*)[responseString JSONValue] objectForKey:#"DataTable"];
NSMutableArray * myArray = [[NSMutableArray alloc] init];
NSMutableDictionary * myDict = [[NSMutableDictionary alloc] init];
if (([(NSString*)sdf isEqual: [NSNull null]])) {
// Showing AlertView Here
}else {
for (int i=0; i<[sdf count]; i++) {
myDict=[sdf objectAtIndex:i];
[myArray addObject:[myDict objectForKey:#"RxnCustomerProfile"]];
}
jsonArray=[myArray mutableCopy];
NSMutableDictionary *dict=[jsonArray objectAtIndex:0];
if ([dict count]>1) {
// Showing AlertView Here
}
}
}
Hi Everyone, I have an issue regarding the -[__NSArrayM objectForKey:]: .
Tried to solve but did not get the better solution for it. Please help me to
find the solution. Thanks In Advance
Below is the issues
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM objectForKey:]: unrecognized selector sent to instance 0x19731d40'
This is a debugging problem and nobody can really solve it for you as you are using non-local variables whose definition and values are unknown, don't mention that you are using SBJSON (I guess), etc. But let's see if we can give you some pointers. Your error:
[__NSArrayM objectForKey:]: unrecognized selector sent to instance
That tells you that you sent a dictionary method (objectForKey) to an array (__NSArrayM). So somewhere you have an array when you think you have a dictionary.
Now you declare and allocate a dictionary:
NSMutableDictionary * myDict = [[NSMutableDictionary alloc] init];
but then assign to it:
myDict=[sdf objectAtIndex:i];
So this discards the dictionary you allocated and instead assigns whatever is at index i in the array sdf. How do you know, as opposed to think, that the element of the array is a dictionary? You don't test to check...
So where did sdf come from? This line:
NSMutableArray *sdf = [(NSDictionary*)[responseString JSONValue] objectForKey:#"DataTable"];
So that calls JSONValue on some unknown string, assumes the result is a dictionary (could it be an array? or a failure?), looks up a key (did your error come from this line?), and assumes the result is an array.
So what you need to do is go and test all those assumptions, and somewhere you'll find an array where you think you have a dictionary.
Happy hunting!
YOU FETCH THE VALUE IN ARRAY FORMAT AND YOU INTEGRATE METHOD IN DICTIONARY.
You do not need to iterate keys and values of dict can directly pass values to array inside else part like:
myArray = [sdf objectForKey:#"RxnCustomerProfile"];
Key RxnCustomerProfile itself containing array not dictionary.
Change your if else part use below code:
if (([(NSString*)sdf isEqual: [NSNull null]])) {
// Showing AlertView Here
}else {
myArray = [sdf objectForKey:#"RxnCustomerProfile"];
}
NSMutableArray *sdf = [(NSDictionary*)[responseString JSONValue] objectForKey:#"DataTable"];
Check Sdf
if([sdf isKindOfClass:[NSDictionary class]])
{
NSLog(#"Dictionary");
}
else if([sdf isKindOfClass:[NSArray class]])
{
NSLog(#"NSArray");
}
else if([sdf isKindOfClass:[NSMutableArray class]])
{
NSLog(#"NSMutableArray");
}
First of all it seems like your json is not actually correctly formatted. Without knowing what responseData looks like it's difficult to say exactly what is wrong. But in your code there are a few areas where it can be improved.
First of all you don't need to use [responseString JSONValue]. You can short circuit it entirely with
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
NSArray *sdf = responseDictionary[#"DataTable"];
Now, the rest all depends on the data in responseData.
But you can make your code a little bit cleaner with (if I understand what you're trying to achieve correctly:
NSMutableArray *myArray = [NSMutableArray array];
if ([sdf isEqual:[NSNull null]]) {
// Showing AlertView here
} else {
for (NSDictionary *myDict in sdf) {
[myArray addObject:dict[#"RxnCustomerProfile"]];
}
}
// No idea what you're trying to achieve here, but here goes:
jsonArray = [myArray mutableCopy];
NSDictionary *dict = jsonArray.first;
if (dict.count > 1) {
// Showing AlertView here
}
Some things to note. You make very liberal use of NSMutableArray and NSMutableDictionary for no apparent reason. Only use mutable if you're actually changing the array or dictionary.

Add Dictionary to NSMutableArray of Dictionaries

I have an NSMutableArray called myMutbaleArray that looks like this when I log it
2015-12-08 17:04:21.679 APP[3342:573379] (
{
id = 19;
"num_test" = 100000;
url = "http://fsad.com";
},
{
id = 20;
"num_test" = 100001;
url = "http://teeeet.com";
}
)
And I want to add an object that looks like this
{
id = 21;
"num" = 100002;
url = "http://example.com";
}
So I am trying this
[myMutbaleArray addObject:#{ #"id":#"23",#"num_test":#"100000", #"url":mainDict[#"website_url"],#"website_name":#"website"}];
But when I do this I get
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'
I initialize the array like this
#interface {
NSMutableArray *socailArray;
}
//inside connectionDidFinishLoading
socailArray = [dataDict valueForKey:#"socail"];
Why can I add another dictionary to the MutableArray?
Thanks
If you see this, your array is actually not a mutable array. Here is the hint:
-[__NSCFArray insertObject:atIndex:]
^^^^^^^^^^^
The object is of type __NSCFArray, which is an internal counterpart of NSArray.
Even if you declare your variable as NSMutableArray the pointer can point to an object of any type (event for example NSRegularExpression). Important is, how it is created.
This happens to most people if they serialise an array either using NSUserDefaults, NSJSONSerialization or what ever.
The key is to create a mutable copy when the array gets deserialised using
-[NSArray mutableCopy]
Note that this is not deep-copy. This means an array contained in the root array will not be mutable copied and needs to be replaced separately.
Deep copying can be achieved using this:
// array
NSArray *originalArray = #[#"a", #"b", #[#1, #2]];
NSMutableArray *mutableArray = (NSMutableArray *)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFArrayRef)originalArray, kCFPropertyListMutableContainers);
// dictionary
NSDictionary *originalDictionary = #{#"a": #"b", #"c": #[#{#"abc": #123}]};
NSMutableDictionary *mutableDictionary = (NSMutableDictionary *)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFDictionaryRef)originalDictionary, kCFPropertyListMutableContainers);
You should change init to:
//inside connectionDidFinishLoading
socailArray = [NSMutableArray arrayWithArray:[dataDict valueForKey:#"socail"]];
Because: [dataDict valueForKey:#"socail"] is a NSArray.
With socailArray = [dataDict valueForKey:#"socail"];, the type of [dataDict valueForKey:#"socail"] is NSArray, so it auto cast socailArray into NSArray, that's why you can not insert thing into this.
To avoid this, you must be hold socailArray as NSMutableArray using:
socailArray = [[dataDict valueForKey:#"socail"] mutableCopy];
Hope this could help.

NSInvalidArgumentException', reason: '-[__NSArrayI length]: unrecognized selector sent to instance 0x165d5150'

Hi I am getting this data form server
NSDictionary*feed=[saveDic objectForKey:#"feed"];
NSLog(#"%#",feed); //Outputs: feed = ( { code = yQ7j0t; "user_id" = 889445341091863; } ); }
NSLog(#"%#",[feed valueForKey:#"code"]);
NSString *referralCode = [feed valueForKey:#"code"];
NSLog(#"%#",referralCode);
self.referralCode.text=referralCode;
And beacuse of that I am getting below error.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI length]: selector sent to instance 0x165d5150'``
Any help will be appreciated.
The issue is, your feed key holds an array. You are not properly handling that in your code, that is why the crash occurs. When you call valueForKey: it retrieves an array of values held by that specific key.
For fixing that you can use:
NSArray *feed = [saveDic objectForKey:#"feed"];
NSArray *referralCodes = [feed valueForKey:#"code"];
NSString *referralCode = referralCodes.count ? referralCodes[0] : #"";
NSLog(#"%#",referralCode);
But I personally prefer using objectForKey: instead of valueForKey:. So you can re-write the code like:
NSArray *feed = [saveDic objectForKey:#"feed"];
NSString *referralCode = feed.count ? [feed[0] objectForKey:#"code"] : #"";
NSLog(#"%#",referralCode);
Some where you use a variable;
yourVaribleName.length
or
[yourVaribleName length]
which should be
yourVaribleName.count
note: the crash says exactly that "yourVaribleName" is NSArray type where you wants length of the NSArray. But NSArray has not feature "length". NSArray has "Count" feature
//try with this code bellow
NSArray *referralCode = [feed valueForKey:#"code"];
NSLog(#"%#",referralCode);
self.referralCode.text=[referralCode componentsJoinedByString:#" "];//#"," or #"" what event you need
Your feed data is in array. So you have retrieve code value from array.Hope it will help you.
NSMutableArray*feed=[saveDic objectForKey:#"feed"];
NSLog(#"%#",feed);
NSLog(#"%#",[feed valueForKey:#"code"]);
NSString *referralCode = [[feed objectAtIndex:indexPath]valueForKey:#"code"];
NSLog(#"%#",referralCode);
self.referralCode.text=referralCode;

-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance [duplicate]

This question already has answers here:
[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance
(2 answers)
Closed 8 years ago.
I'm trying to parse through an API for my iOS app. However, for some reason the API returns JSON that I can't seem to parse (using NSJSONSerialization). Since I don't know the names of player1 and player 2 constantly I can't use objectForKey (which in testing, ex knowing player1 is the name of a player etc, works). So I use objectAtIndex which causes a crash, "-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance".
JSON:
{
"id": "idnumb",
"numentrants": 2,
"entrants": {
"player1": {
"displayname": "player1",
"otherdata": 1234,
},
"player2": {
"displayname": "player2",
"otherdata": 5678,
}
}
}
Obj C:
NSError *jsonParsingError = nil;
NSDictionary *eventArray = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonParsingError];
for(int i = 0; i < [[eventArray objectForKey:#"entrants"] count]; i++)
{
NSArray *entrantsArray = [[eventArray objectForKey:#"entrants"] objectAtIndex:i];
NSLog(#"%#", entrantsArray);
}
Thanks
Entrants is a dictionary, not an array. :)
You can use the NSObject isKindOfClass method to check whether elements of the parsed JSON are dictionaries or arrays, and then handle them appropriately.
If you want to access a dictionary's values by index, you can retrieve an array of values by calling NSDictionary's allValues method.
None of the objects in your JSON data are arrays, there are only dictionaries. You need to enumerate over it like a dictionary, not an array, for example:
NSDictionary *entrants = [eventArray objectForKey:#"entrants"];
for(NSString *playerName in entrants)
{
NSLog(#"%#", playerName);
NSDictionary *playerData = [entrants objectForKey:playerName];
for (NSString *dataName in playerData)
{
NSLog(#"%#: %#", dataName, [playerData objectForKey:dataName]);
}
}

Weird crash while accessing array objects at a given index in IOS

We have the following method where we are trying to access an array object at a given index. The array is resultArr. When we do a resultArr count it gives us a result of 13. So we know that the array is not null but when we try to do objectAtIndex it crashes with the error.
Function:
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSArray *keys = [json allKeys];
NSLog(#"keys: %#",keys);
NSArray* htmlAttributions = [json objectForKey:#"html_attributions"]; //2
NSArray* resultArr = (NSArray *)[json objectForKey:#"result"]; //2
NSArray* statusArr = [json objectForKey:#"status"]; //2
NSLog(#"htmlAttributions: %#",htmlAttributions);
NSLog(#"result: %#", resultArr); //3
NSLog(#"status: %#", statusArr); //3
NSLog(#"resultCount: %d",[resultArr count]);
[resultArr objectAtIndex:0];
}
Error:
2012-04-01 22:31:52.757 jsonParsing[5020:f803] resultCount: 13 2012-04-01 22:31:52.759 jsonParsing[5020:f803] -[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x6d2f900 2012-04-01 22:31:52.760 jsonParsing[5020:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x6d2f900'
*** First throw call stack:
Thank you.
The error message is fairly descriptive. One of the objects that your code expects to be an NSArray is actually an NSDictionary. You cannot access fields inside of an NSDictionary by using NSArray methods (and casting from NSDictionary* to NSArray* will not convert an NSDictionary into an NSArray).
This would mean that inside of the JSON, one of your elements was serialized as an object/associative array instead of as a plain array. You can easily determine which one by looking at your JSON data as text, and finding the item that uses { and } instead of [ and ].
You are saying
NSArray* resultArr = (NSArray *)[json objectForKey:#"result"]; //2
But that does not make this object ([json objectForKey:#"result"]) an NSArray. It is an NSDictionary, and sending it a message that NSDictionary does not respond to (objectAtIndex:) causes a crash.
You were able to send it the count message without crashing because NSDictionary does happen to respond to the count message. But your preconception that this is an array is still mistaken.
You cannot cast an NSDictionary* to an NSArray* as you tried to do with this line: NSArray* resultArr = (NSArray *)[json objectForKey:#"result"];, then call -objectAtIndex.

Resources