Getting the error in JSON parsing in iphone - iphone

I am trying to pars the json data and display in table
My JSON data is like this
{"isError":false,"ErrorMessage":"","Result":{"Count":4,"Data":[{"ContentID":"127_30_1309793318065","ContentTypeID":1,"UserCaption":"Gandhinagar(Kanjurmarg)","UserComment":"central\n","DateRecorded":"\/Date(1309793318000+0530)\/","Data":"","ShareType":true,"Views":0,"PlayTime},{},{},{}];};isError = 0;}
I am prasing like this
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *loginStatus = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
NSLog(#"%#",loginStatus);
//this is for the getting the data from the server with help of JSON
NSString *json_string = [[NSString alloc] initWithData:webData encoding:NSUTF8StringEncoding];
NSDictionary *result = [json_string JSONValue];
/
//this for holding the Array value which come from the server
NSMutableArray *results = [[NSMutableArray alloc] init];
for (int index = 0; index<[reviewsvalues count]; index++)
{
NSMutableDictionary * value = [reviewsvalues objectAtIndex:index];
ReviewsResult * result = [[ReviewsResult alloc] init];
result.User_Caption = [value objectForKey:#"UserCaption"];
result.ContentType_Id = [value objectForKey:#"DateRecorded"];
result.Average_Rating = [value objectForKey:#"AverageRating"];
//OVER here MY APP GET CRASH
}
}
BUt it get crash and give error
[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance

The problem is simple.
reviewsvalues should be an NSDictionary and you should not be calling objectAtIndex: for the reviewsvalues.
Instead you should call valueForKey like
int count = [[reviewsvalues valueForKey:#"Count"] intValue];
NSArray *reviewsArray = [reviewsvalues valueForKey:#"Data"];
int count = [reviewsArray count];
cell.textLabel.text = [[reviewsArray objectAtIndex:indexPath.row] valueForKey:#"ContentID"];
Hope this helps you.
Please let me know if you want more help on this.

You set reviewsvalues = [result objectForKey:#"Result"];
Which means reviewsvalues is now an NSDictionary.
"Result" is a dictionary, not an array:
{"Count":4,"Data":[...]}
NSDictionary doesn't respond to -objectAtIndex:, that's one of NSArray's methods.
You need another step:
NSArray *reviewsArray = [reviewsvalues objectForKey:#"Data"];
and while you are at it, you can use fast enumeration.
for (NSDictionary *review in reviewsArray) {
ReviewsResult * result = [[ReviewsResult alloc] init];
result.User_Caption = [review objectForKey:#"UserCaption"];
result.ContentType_Id = [review objectForKey:#"DateRecorded"];
result.Average_Rating = [review objectForKey:#"AverageRating"];
}
Edit: also, you should know that you've not coded this very defensively. What happens if the data isn't exactly as it is in your example? what happens if a value is missing, like "Data", or "Result"?
Your app should be robust enough to not choke if something slightly unexpected happens.

Related

how can adding Key float values from NSDictionary to NSarray?

My brain is fried! I can't think.
i am new to iphone programming
am doing json parsing ....in that am storeing data from json to nsdictionary but .......
I want to add all nsdictionary float values from the dictionary to the array. This is what I am doing right now.As code below:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
self.responseData = nil;
dict = [responseString JSONValue];
NSMutableArray *array = [NSMutableArray array];
for (NSString *key in [dict allKeys])
{
array = [dict objectForKey:key];
// array return float values but
[array addObject:array ]; // geting carsh dude to array return float values like 120.01
}
Please guide me i am not getting a part where i am doing a mistake.
Thanks in advance.
Your app is crashing because you are adding data to NSArray , this is static array, you can not add value at run time, so just Make NSMutableArray and add your data in NSMutableArray.
Your code is broken in a couple of ways.
This line assigns the array pointer to the object in the dictionary:
array = [dict objectForKey:key];
Then you are trying to add the array to itself, which does not make sense. But worse, since array does no longer point to your NSMutableArray you cannot even call that method.
[array addObject:array ];
You probably wanted to do something like this:
for (NSString *key in [dict allKeys])
{
id value = [dict objectForKey:key];
[array addObject:value];
}

Objective-C: NSDictionary and looping through inner NSDictionaries

I get the following NSDictionary when I parse a JSON response from my server:
(
{
fromUname = Ben;
id = ci2n9awef7tm7e142sx;
message = hi;
read = 1;
subject = hi;
time = 1316513972;
toUname = Jill;
},
{
fromUname = Eamorr;
id = asdf98s14u7tm7e142sx;
message = asdf;
read = 0;
subject = asdf;
time = 1316513322;
toUname = Jack;
}
)
I'm really struggling to extract the two subjects.
Here's what I've coded sofar (incomplete...):
...
SBJsonParser *parser=[[SBJsonParser alloc]init];
NSDictionary *obj=[parser objectWithString:[request responseString] error:nil];
NSLog(#"%#",obj);
NSLog(#"%d",[obj count]);
for(int i=0;i<[obj count];i++){
NSDictionary *message=[obj objectForKey:];
NSLog(#"%#",[message objectForKey:#"subject"]); //I'm stuck...
}
...
Can anyone give me some efficient way of extracting the subjects?
Many thanks in advance,
Its actually an NSArray of NSDictionaries. So to get the information, loop through the array and get the dictionary:
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSArray *obj = [parser objectWithString:[request responseString] error:nil];
NSLog(#"%# : %d",obj, [obj count]);
for (NSDictionary *dict in obj) {
NSLog(#"%#", [dict objectForKey:#"subject"]);
}

NSMutable Array always adding the same pointer

The following code should add different objects to an NSMutableArray however it adds the same object each time:-
for(int i =0; i < [results count];i++)
{
Reservation *r = [[Reservation alloc] init];
NSDictionary *dict = [results objectAtIndex: i];
r.resId = [dict objectForKey:#"reservationrequest_id"];
r.driver = [dict objectForKey:#"driver_name"];
r.vehicle = [dict objectForKey:#"billing_registration"];
r.startDate = [dict objectForKey:#"hire_from_date"];
r.endDate = [dict objectForKey:#"hire_to_date"];
r.status = [dict objectForKey:#"status_type"];
[self.bookingsObjectArray addObject:r];
[r release];
r = nil;
}
I have exactly the same code that works fine in another part of my app it just uses a Groups class instead of Reservation.
When debugging the code I found that when it does [r release]; 'r' is greyed out but still keeps the same pointer. When it goes back to Reservation *r = [[Reservation alloc] init];
'r' has the same pointer as last time.
Any ideas what might be causing the problem? Thanks in advance.
Chris

Creating a long NSString causing memory issues

My code below is causing my app to quit i.e. get black screen and then see in debugger console: Program received signal: “0”.
Basically it is causing problem when my orderArray has count of 2000 or more. I am using iPhone 3GS with iOS 4.2
Question: Is there a more efficient and less memory consuming way to create my long outStr?
NSString *outStr = #"";
for (int i = 0; i < count; i++) {
NSDictionary *dict = [[ARAppDelegate sharedAppDelegate].orderArray objectAtIndex:i];
outStr = [outStr stringByAppendingFormat:#"%#,%#,%#,%#\n",
[dict valueForKey:#"CODE"],
[dict valueForKey:#"QTY"],
[[ARAppDelegate sharedAppDelegate].descDict valueForKey:[dict valueForKey:#"CODE"]],
[[ARAppDelegate sharedAppDelegate].priceDict valueForKey:[dict valueForKey:#"CODE"]]];
}
Update: Thanks to very kind people who helped, below is my modified code:
NSArray *orderA = [ARAppDelegate sharedAppDelegate].orderArray;
NSDictionary *descD = [ARAppDelegate sharedAppDelegate].descDict;
NSDictionary *priceD = [ARAppDelegate sharedAppDelegate].priceDict;
NSMutableString *outStr = [[[NSMutableString alloc] init] autorelease];
for (int i = 0; i < [orderA count]; i++) {
NSDictionary *dict = [orderA objectAtIndex:i];
NSString *code = [dict valueForKey:#"CODE"];
[outStr appendFormat:#"%#,%#,%#,%#\n",
code,
[dict valueForKey:#"QTY"],
[descD valueForKey:code],
[priceD valueForKey:code]];
}
[self emailTxtFile:[NSString stringWithString:outStr]];
// This reaches end of method
The problem is that in every iteration a new string object is formed. This consumes a lot of memory. One solution could be to use a local autoreleasepool, but that's rather complicated here.
You should use an NSMutableString, like:
NSMutableString *outStr = [[[NSMutableString alloc] init] autorelease];
for (int i = 0; i < count; i++) {
NSDictionary *dict = [[ARAppDelegate sharedAppDelegate].orderArray objectAtIndex:i];
[outStr appendFormat:#"%#,%#,%#,%#\n",
[dict valueForKey:#"CODE"],
[dict valueForKey:#"QTY"],
[[ARAppDelegate sharedAppDelegate].descDict valueForKey:[dict valueForKey:#"CODE"]],
[[ARAppDelegate sharedAppDelegate].priceDict valueForKey:[dict valueForKey:#"CODE"]]];
}
Then you can use outStr, just as if it was an NSString. As Tom points out in the comments, you could turn the NSMutableString into an NSString when you're finished, using:
NSString *result = [NSString stringWithString:outStr];
[outStr release]; // <-- add this line and remove the autorelease
// from the outStr alloc/init line
making your code re-usable and easier to maintain.

obj-c problem setting array with componentsSeperatedByString

I have a data source with about 2000 lines that look like the following:
6712,Anaktuvuk Pass Airport,Anaktuvuk Pass,United States,AKP,PAKP,68.1336,-151.743,2103,-9,A
What I am interested in is the 6th section of this string so I want to turn it into an array, then i want to check the 6th section [5] for an occurrance of that string "PAKP"
Code:
NSBundle *bundle = [NSBundle mainBundle];
NSString *airportsPath = [bundle pathForResource:#"airports" ofType:#"dat"];
NSData *data = [NSData dataWithContentsOfFile:airportsPath];
NSString *dataString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
NSArray *dataArray = [dataString componentsSeparatedByString:#"\n"];
NSRange locationOfAirport;
NSString *workingString = [[NSString alloc]initWithFormat:#""];
NSString *searchedAirport = [[NSString alloc]initWithFormat:#""];
NSString *airportData = [[NSString alloc]initWithFormat:#""];
int d;
for (d=0; d < [dataArray count]; d=d+1) {
workingString = [dataArray objectAtIndex:d];
testTextBox = workingString; //works correctly
NSArray *workingArray = [workingString componentsSeparatedByString:#","];
testTextBox2 = [workingArray objectAtIndex: 0]; //correctly displays the first section "6712"
testTextBox3 = [workingArray objectAtIndex:1] //throws exception index beyond bounds
locationOfAirport = [[workingArray objectAtIndex:5] rangeOfString:#"PAKP"];
}
the problem is that when the workingArray populates, it only populates with a single object (the first component of the string which is "6712". If i have it display the workingString, it correctly displays the entire string, but for some reason, it isn't correctly making the array using the commas.
i tried it without using the data file and it worked fine, so the problem comes from how I am importing the data.
ideas?
You code works. You should run it with the debugger to see what's happening. At a guess, your input data isn't what you think it is - possibly a different encoding, or different line endings.
See sample:
NSString *dataString = #"6712,Anaktuvuk Pass Airport,Anaktuvuk Pass,United States,AKP,PAKP,68.1336,-151.743,2103,-9,A";
NSArray *dataArray = [dataString componentsSeparatedByString:#"\n"];
for (NSString *workingString in dataArray) {
NSString *testTextBox = workingString; //works correctly
NSArray *workingArray = [workingString componentsSeparatedByString:#","];
NSString *testTextBox2 = [workingArray objectAtIndex: 0]; //correctly displays the first section "6712"
NSString *testTextBox3 = [workingArray objectAtIndex:1]; //throws exception index beyond bounds
NSRange locationOfAirport = [[workingArray objectAtIndex:5] rangeOfString:#"PAKP"];
}
there was a problem in the data where there were a few "\"s that caused the errors.