parsing JSON using objective C? - objective-c

I have spent 1 week studying objective C. Now I am quite confused at the dealing with data part.
My friend gave me a link
http://nrj.playsoft.fr/v3/getQuiz.php?udid=23423455&app=2
and ask me write a class to parse this JSON. I had no clue what parsing JSON means. but I have gone online and looked up. I could understand a basics of it and then I impletemented a punch of code to parse this JSON. Which is:
-
(void)parseURL
{
//create new SBJSON object
SBJSON *parser = [[SBJSON alloc] init];
NSError *error = nil;
//perform request from URL
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://nrj.playsoft.fr/v3/getQuiz.php?udid=23423455&app=2"]];
// Perform request and get JSON back as a NSData object
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
// Get JSON as a NSString from NSData response
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
// parse the JSON response into an object
NSDictionary *results = [parser objectWithString:json_string error:&error];
// array just for the "answer" results
NSArray *quizes = [results objectForKey:#"quiz"];
NSDictionary *firstQuiz = [quizes objectAtIndex:0];
// finally, the name key
NSString *extract = [firstQuiz objectForKey:#"extract"];
NSLog(#"this is: %#", [extract valueForKey:#"extract"]);
}
This is at the implementation file, but in the header file I could not declare any variables, it will print out some errors. I tried to run this, there is no errors, but I am not sure this code is correct or not. And my friend asked me to write a class into an existing project. I don't know what needs to be modified and what not. I am so blur right now. Could anyone pro in this give me a hand. ?
My sincere thanks.
Thanks for reply. I have downloading and added the JSON framework ealier too. I am just not sure where to begin and where to end, meaning the step I should do when I add JSON framework into it. I could understand the syntax but I am not sure about the steps I should do. I am a newbie in this.

If you support iOS 5.0+, you should use built-in NSJSONSerialization.
It is faster than TouchJSON.

You could just use TouchJSON: http://code.google.com/p/touchcode/wiki/TouchJSON
Or you could use this one: http://code.google.com/p/json-framework/
I'm sure there are others. I use TouchJSON... it's fast and has a good API.

I recommend working through Ray Wenderlich's MapKit tutorial, especially if you are a newbie. It covers several common iOS development issues, including parsing JSON data.
http://www.raywenderlich.com/2847/introduction-to-mapkit-on-ios-tutorial
"The Implementation" section is where his JSON feed is retrieved and then in "Plotting the Data" he uses the SBJson library to parse it.

Related

Convert Unicode \u009e to acute accent from JSON

I am using Xcode in objective-C and I try to figure out how I could convert "\U009e" character to "é" but I am still stuck despite a lot of discussions about this topic.
Basically, I have created inside my Xcode project a JSON file that looks like this:
{
"ééé":["1"],
}
When I get the file by the NSJSONSerialization method:
NSString *dataPath = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"json"];
id jsonObject = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:dataPath] options:kNilOptions error:&error];
I end up with unicode characters (like \U009e) instead of an acute accent. I know I need to find a way to convert/decode/... during the process but I don't know how to do it.
Would anyone have an idea?

data parameter is nil when i trying to fetch the data from web service using json

- (NSDictionary*)PostWebService:(NSString*)completeURL param:(NSString*)value
{
#try
{
NSString *urlStr =[completeURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
//NSString *urlPart=#"req=value";
//NSString *urlPart;
NSString *urlPart=[NSString stringWithFormat:#"req=%#", value];
NSLog(#"String %#",urlPart);
NSData *requestBody = [urlPart dataUsingEncoding:NSUTF8StringEncoding];
//NSLog(#"String %#",requestBody);
[request setHTTPBody:requestBody];
NSURLResponse *response = NULL;
NSError *requestError = NULL;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&requestError];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding] ;
NSLog(#"String %#",responseString);
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions
error:&error];
return json;
}
#catch(NSException *e)
{
NSLog(#"reason is%#",e.reason);
}
}
and i call this method here..
-(NSDictionary*)gotvall:(NSString*)req
{
#try
{
NSString *vurl=#"some url/";
// vurl=[vurl stringByAppendingString:#"req="];
// vurl=[vurl stringByAppendingString:req];
// NSLog(#"%#",vurl);
NSDictionary *json=[self PostWebService:vurl param:req];
NSLog(#"json is%#",json);
return json;
}
#catch(NSException *e)
{
NSLog(#"%#",e.reason);
}
}
After debugging this method I got result as data parameter is nil.
Can anyone tell that what I am doing wrong here.
I got the complete url and when I run that url on browser I got the perfect data but when I printing the value of json it returns null.
You reported that your error was:
Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo=0x8d84960 {NSErrorFailingURLStringKey=%20http://www.hugosys.in/www.nett-torg.no/api/vehicl‌​e/, NSErrorFailingURLKey=%20http://www.hugosys.in/www.nett-torg.no/api/vehicle/, NSLocalizedDescription=unsupported URL, NSUnderlyingError=0x8d8bfe0 "unsupported URL"}
That %20 in your error message is a space at the start of your URL that your stringByAddingPercentEscapesUsingEncoding call converted to %20. If you remove that extra space, you should be in good shape.
A couple of other observations:
Just to warn you, your use of stringByAddingPercentEscapesUsingEncoding will correctly handle the presence of a space in the req value. But it will not properly handle the presence of certain other characters (notably & or +). If it's possible that those sorts characters might appear in the req value, you might want to remove the call to stringByAddingPercentEscapesUsingEncoding for the whole URL, and instead just use CFURLCreateStringByAddingPercentEscapes (which gives you a little more control over the percent escaping process) on just the req value. See the percentEscapeString method in this answer: Append data to a POST NSURLRequest.
In both your network request as well as your JSON parsing process, you are returning an NSError object. I might suggest that you log those values if they're ever non-nil, which will help you diagnose problems in the future.
I notice that you are using exception handling. That's not common in Objective-C. As the Programming in Objective-C guide says:
Dealing with Errors
Almost every app encounters errors. Some of these errors will be outside of your control, such as running out of disk space or losing network connectivity. Some of these errors will be recoverable, such as invalid user input. And, while all developers strive for perfection, the occasional programmer error may also occur.
If you’re coming from other platforms and languages, you may be used to working with exceptions for the majority of error handling. When you’re writing code with Objective-C, exceptions are used solely for programmer errors, like out-of-bounds array access or invalid method arguments. These are the problems that you should find and fix during testing before you ship your app.
All other errors are represented by instances of the NSError class. This chapter gives a brief introduction to using NSError objects, including how to work with framework methods that may fail and return errors. For further information, see Error Handling Programming Guide.
Bottom line, As I mentioned in the second point, you should be checking NSError return values yourself rather than relying on exceptions in Objective-C.

NSstream write encoding issues

Im trying to send a string using NSoutputstream , however i cant seem to get the encoding right , using dataWithContentsOfURL works
im using a nodejs TCP server with actionHero library.
it works using netcat and telnet.
- (IBAction)sendText:(id)sender {
NSString *response = [NSString stringWithFormat:#"%#", [_sendTextField.text stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
NSLog(#"writing %#",response);
///////////////////////////// this line works/////////////////////////////////////////////////////
// NSData *data = [[NSData alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.google.com"]]];
///////////////////////////// this line doesnt work/////////////////////////////////////////////////////
NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSUTF8StringEncoding]];
//%u returns a non zero value
NSLog(#"%u",[outputStream write:[data bytes] maxLength:[data length]]);
}
i get a null streamError from handle stream Event method
Not knowing the content of response, I can't give you a specific answer as to why NSUTF8StringEncoding doesn't work with it. Generally speaking, however, if there is a byte sequence in your content that is incompatible with UTF-8, you're going to get nil when you call -dataUsingEncoding:.
There's a strategy that I learned from reading Mike Ash's blog (look under the section "Fallbacks"), and it's served me pretty well in situations such as yours.
To briefly sum it up, first try using NSUTF8StringEncoding. If that doesn't work, try using NSISOLatin1StringEncoding. And if that doesn't work, try using NSMacOSRomanStringEncoding. Mike's blog has the rationale for this.
Found the answer to my own question. turns out the problem is in actionHero's on data method where it looks for a /n which is not provided by the ios application. appended a \n and its fine now

NSJSONSerialization not working as intended for Stack overflow API

I am trying to use NSJSONSerialization to serialize the data returned from stack overflow API, but it is not working as intended :(
I am using code as below :
NSURL *apiURL = [NSURL URLWithString:#"http://api.stackoverflow.com/1.1/questions?tagged=objective-c&pagesize=30"];
NSError *error = nil;
// First option - failed
NSInputStream *inputStream = [NSInputStream inputStreamWithURL:apiURL]; // returning nil
id jsonFound1 = [NSJSONSerialization JSONObjectWithStream:inputStream options:NSJSONReadingMutableContainers error:&error];
// Second option - failed
NSData *jsonData = [NSData dataWithContentsOfURL:apiURL]; // returning correct value, verified after converting it to NSString
id jsonFound2 = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; // returning nil
I am trying the above code in Xcode 4.2 for iOS5 and I am getting (null) for inputStream and for jsonFound2.
Earlier I was doing it through SBJSON and it was working correctly.
Can anyone suggest me if I am doing anything wrong or missing anything?
I think there may be a missing step after assigning an inputStream.
[inputStream open];
I have not tried this with remote URLs, but have seen examples that use this approach.
First option does not work because it supports only file url (thanks to David for pointing).
Second option works fine for remote urls.

How to handle the exceptions

NSString *stringURL=[[NSString alloc] init];
stringURL=[stringURL stringByAppendingFormat:kSearchBarURL,text.text];
NSString *url = [NSString stringWithString:stringURL];
NSData *data1 = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
NSString *responseids = [[NSString alloc] initWithData:data1 encoding:nil];
responseids = [responseids stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"\n\r\t"]];
SBJsonParser *parser=[SBJsonParser new];
NSData *data = [parser objectWithString:responseids error:nil];
NSMutableDictionary *searchURL = (NSMutableDictionary*)data;
I coded this i did not handle the exception for my code.
doing json and calling the service url and loading the data.
the application get crashes when my service is too low or no service found.
How to handle the exception for my code here..
Do I use #try #catch.
or
NSURLConnection for error handling.
Please help me out .
Thanks in advance.
Whenever an API makes use of NSError, you should use this rather than wrapping things up in a try…catch block as NSError is designed exactly for this. I usually reserve #try for things where I am really not able to anticipate what might go wrong. If NSError is in the mix, then you know that there is a potential for a problem that you should be handling gracefully.
More generally, your code has some strange stuff in it. You alloc init an empty NSString and then create a new string by appending a format. Not sure why you don't just use [NSString stringWithFormat]. Once you have the string, you can create the URL without the NSString *url bit.
You're also using a synchronous call to what I assume is a remote server. This has the potential to bog down your application if/when the server is not available. You're also not telling NSString what kind of encoding you expect your string to be in when it reads it from NSData. A better method depending on your server side would be to use NSString's stringWithContentsOfURL:usedEncoding:error: method. I would recommend that you use the various NSURLConnection callbacks. Have a look at the URL Loading System Programming Guide on Using NSURLConnection The NSURLConnection delegate methods are the ones you want to implement to provide this asynchronous processing.
For your trimming, you might be interested in the +whitespaceAndNewlineCharacterSet method on NSCharacterSet.
Finally, for your JSON parsing, you might be interested in the category that the SBJSON code adds to NSString, particularly -JSONValue which will give you the dictionary or array representation (as appropriate) of the NSString when parsed as JSON by SBJSON.
HTH