I am a newbie in iOS development. I was trying to put the results of an NSMutableArray into an NSMutableString but this is resulting in an NSException.
Here is my code:
NSMutableArray *oldtableData = .......this is where I recieve card data;
NSError *error;
NSMutableData *tableDataUpdated = [[NSJSONSerialization dataWithJSONObject:oldtableData
options:0
error:&error] copy];
NSMutableDictionary *cardDictionary = [NSJSONSerialization JSONObjectWithData:tableDataUpdated options:0 error:NULL];
For converting the cardDictionary into a NSMutableArray, I am using this piece of code (which is giving me an NSException)
NSMutableArray *type = [NSMutableArray array];
NSMutableArray *last4Digits = [NSMutableArray array];
[cardDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[type addObject:[obj valueForKeyPath:#"type"]];
[last4Digits addObject:[obj valueForKeyPath:#"last4Digits"]];
}];
But If I exclude the above code and try NSLog with this piece of code
NSLog(#"JSON: %#",cardDictionary);
Console will give a proper json result; something like this:
JSON: (
{
cardPciId = "###########";
fingerPrint = ###########;
last4Digits = 4321;
type = Mastercard;
},
{
cardPciId = "###########";
fingerPrint = ###########;
last4Digits = 1234;
type = Visa;
}
)
I am trying to convert this into two Arrays, one with all the "type"s and another one with all "last4Digits". But this is what I get
Uncaught exception: -[__NSCFArray enumerateKeysAndObjectsUsingBlock:]:
unrecognized selector sent to instance 0x7ff7060badf0
I tried to hover through StackOverFlow to find a solution but none of them seem to be working. :(
It looks like cardDictionary is actually an NSArray instance containing the dictionaries. So, you should iterate through the array, and get type and last4Digits from each dictionary using objectForKey instead of valueForKeyPath:
NSArray *cardDictionaries = [NSJSONSerialization JSONObjectWithData:tableDataUpdated options:0 error:NULL];
NSMutableArray *type = [NSMutableArray array];
NSMutableArray *last4Digits = [NSMutableArray array];
[cardDictionaries enumerateObjectsUsingBlock:^(NSDictionary *cardDictionary, NSUInteger idx, BOOL *stop) {
[type addObject:[cardDictionary objectForKey:#"type"]];
[last4Digits addObject:[cardDictionary objectForKey:#"last4Digits"]];
}];
There is a lot going on here, but I want to point one thing out.
Table data is being serialized to JSON.
NSMutableData *tableDataUpdated = [[NSJSONSerialization dataWithJSONObject:oldtableData
options:0
error:&error] copy];
Next, the data that was just serialized is de-serialized. It will always be the same array.
NSMutableDictionary *cardDictionary = [NSJSONSerialization JSONObjectWithData:tableDataUpdated options:0 error:NULL];
You will always get the same data back. You don't need to do the JSON step at all.
Related
- (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.
Response:
{"rsBody":
[{"productId":11,
"productImageUrl":"http:xxxx"},
{"productId":9,
"productImageUrl":"http:"xxxx"}]}
I know this is a repeated question, but still asking cause not getting the right way to do it. I am getting some response from php server as JSON in an array which consists two objects. I want to map the element of both objects productImageUrl in an NSArray. Resultant array should be somewhat like
NSArray =[{#"url":"productImageUrl1"},{#"url":#"ProductImageUrl2"}, nil];
productImageUrl1 = element of 1st object, productImageUrl2 = element of 2nd object.
I am parsing the response and able to to extract it from rsBody.
NSDictionary* response=(NSDictionary*)[NSJSONSerialization
JSONObjectWithData:receivedData options:kNilOptions error:&tempError];
NSArray *rsBody = [response objectForKey:#"rsBody"];
Try this:
NSMutableArray *arr = [[NSMutableArray alloc] init];
NSDictionary* response = [NSJSONSerialization JSONObjectWithData:receivedData options:kNilOptions error:&tempError];
NSArray *rsBody = [response objectForKey:#"rsBody"];
for (NSDictionary *dict in rsBody)
{
NSMutableDictionary *dictURL = [[NSMutableDictionary alloc] init];
[dictURL setValue:[dict valueForKey:#"productImageUrl"] forKey:#"url"];
[arr addObject:dictURL];
}
NSLog(#"%#", arr);
When I try to print array of json values in log, I get addresses instead of values. Here's how I coded.
NSData *jsonData = [json dataUsingEncoding:NSASCIIStringEncoding];
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
NSMutableArray *tempArray = [NSMutableArray arrayWithCapacity:jsonArray.count];
NSMutableArray *anotherTempArray = [NSMutableArray arrayWithCapacity:jsonArray.count];
NSDictionary *dict;
for(dict in jsonArray)
{
NSString *projectName = dict[#"Name"];
NSString *urlText = dict[#"Url"];
NSLog(#"Url text in array = %#", urlText);
NSString *attch = dict[#"attachmentes"];
NSLog(#"Attached url in array = %#", attch);
NSString *projID = dict[#"ProjectID"];
NSLog(#"Project ID in array = %#", projID);
SaveAttachment *saveAt = [[SaveAttachment alloc] initWithName:projectName withList:#"View" withAttachment:#"View"];
[tempArray addObject:saveAt];
SaveProjectId *saveProj = [[SaveProjectId alloc] initWithProjectId:projID];
saveProj.projectId = projID;
[anotherTempArray addObject:saveProj];
}
array = tempArray;
[self.tableViewProject reloadData];
NSLog(#"Array of project IDs === %#", anotherTempArray); //Get values (array of project ids here.
}
Replace
SaveProjectId *saveProj = [[SaveProjectId alloc] initWithProjectId:projID];
saveProj.projectId = projID;
[anotherTempArray addObject:saveProj];
with
[anotherTempArray addObject:projID];
This is because your anotherTempArray contains objects of SaveProjectId ie, everytime in for loop you are adding saveProj object not projID. Thats why your array showing SaveProjectId objects.
If you want to directly save them, then use the below modification
[anotherTempArray addObject:projID];
or you can use like(this is i would prefer)
NSLog(#"First project ID === %#", [anotherTempArray objectAtindex:0] projectId]);
You are storing SaveProjectId objects in the array, therefore when you print the content you see the address of those objects.
your "anotherTemoArray" is having objects of SaveProbectId so you have to pass object at index to SaveProjectId and then you can see the array information
When calling NSLog(#"Array of project IDs === %#", anotherTempArray); the -(NSString*)description method on each of the objects inside 'anotherTempArray' is being called.
In your case that means -(NSString*)description is being called on SaveProjectId objects. Override it to print out what you want... e.g.
-(NSString*)description {
return [NSString stringWithFormat:#"SaveProjectId: %#",self.projectId];
}
I have json data as below.
[
{"id":"2","imagePath":"image002.jpg","enDesc":"Nice Image 2"},
{"id":"1","imagePath":"image001.jpg","enDesc":"Nice Image 1"}
]
I am assigning this to variable named NSArray *news.
Now I have three different array as below.
NSArray *idArray;
NSArray *pathArray;
NSArray *descArray;
I want to assign data of news to these arrays so that finally I should have as below.
NSArray *idArray = #["2","1"];
NSArray *pathArray = #["image002.jpg","image001.jpg"];
NSArray *descArray = #["Nice Image 2","Nice Image 1"];
Any idea how to get this done?
With the help of below answer this is what I did.
pathArray = [[NSArray alloc] initWithArray:[news valueForKey:#"imagePath"]];
I don't wanted to use NSMutableArray for some reasons.
You should use JSONKit or TouchJSON to convert your JSON data to Dictionary.
Than you may do this :
NSArray *idArray = [dictionary valueForKeyPath:#"id"]; // KVO
Use this
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:receivedData options:NSJSONReadingMutableContainers error:nil];
then you can extract all the information that you need from there you have NSArray that contains NSDictionary , where you can go and use objectForKey: to get all the info you need.
Load the json data into an NSDictionary, which you may call "news" . Then retrieve as
NSArray *idArray = [news valueForKeyPath:#"id"];
NSArray *pathArray = [news valueForKeyPath:#"imagePath"];
NSArray *descArray = [news valueForKeyPath:#"enDesc"];
Yes all the above ans is correct I am just integrating all of them together to be easly use to you:
NSArray *serverResponseArray = [NSJSONSerialization JSONObjectWithData:receivedData options:NSJSONReadingMutableContainers error:nil]; // I am assigning this json object to an array because as i show it is in array format.
now:
NSArray *idArray = [[NSMutableArray alloc] init];
NSArray *pathArray = [[NSMutableArray alloc] init];
NSArray *descArray = [[NSMutableArray alloc] init];
for(NSDictionary *news in serverResponseArray)
{
[idArray addObject:[news valueForKey:#"id"]];
[pathArray addObject:[news valueForKey:#"imagePath"]];
[descArray addObject:[news valueForKey:#"enDesc"]];
}
I'm currently trying to parse this JSON
[{"id":"1","dish_name":"Pasta & ketchup","category":"main","rating":"5","rating_count":null,"author":"Me","ingredients":"Pasta\nKetchup\nWater","description":"Very good for students\nCheap too!","picture":null,"protein":"7","fat":"11","carbs":"12","calories":"244","developer_lock":"1"},{"id":"2","dish_name":"Pasta & Kødsovs","category":"main","rating":"5","rating_count":null,"author":"Me","ingredients":"Pasta\nKødsovs\nWater","description":"Very good for students\nCheap too!","picture":null,"protein":"7","fat":"11","carbs":"12","calories":"244","developer_lock":"1"}]
But it fails and crashes with this code
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
NSError *error = NULL;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
recipes = [[NSArray alloc] initWithArray:[json objectForKey:#"dish_name"]];
[uit reloadData];
}
Do someone have any clue, why it crashes with error -[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x8077240
?
Thanks in advance.
The error message beginning with [__NSCFArray objectForKey:] means that you have an NSArray (the root object of the JSON is an array - notice the opening and closing square brackets) and you're trying to treat it as a dictionary. All in all,
recipes = [[NSArray alloc] initWithObject:[json objectForKey:#"dish_name"]];
should be
recipes = [[NSArray alloc] initWithObject:[[json objectAtIndex:0] objectForKey:#"dish_name"]];
Note that there are two objects in the array, so you might want to use [json objectAtIndex:1] as well.
Edit: if you have a dynamic number of recipes, you can do this:
recipes = [[NSMutableArray alloc] init];
for (NSDictionary *dict in json) {
[recipes addObject:[dict objectForKey:#"dish_name"]];
}
If your json NSDictionary were a real & valid NSDictionary object, your call to this:
[json objectForKey:#"dish_name"]
should return exactly this:
"Pasta & ketchup"
Which is definitely not an array. It's a NSString object.
Which would be why the call to "initWithArray" is bombing.