Problems with JSON on iOS - iphone

I'm trying to parse the JSON file at this URL: http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22YHOO%22%2C%22AAPL%22%2C%22GOOG%22%2C%22MSFT%22)%0A%09%09&format=json&diagnostics=true&env=http%3A%2F%2Fdatatables.org%2Falltables.env&callback=results
The code that I have so far is as follows:
NSData *data=[NSData dataWithContentsOfURL:[[NSURL alloc] initWithString:url]];
NSError *error = nil;
id myJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
NSLog(#"%#", error);
NSArray *jsonArray = (NSArray *)myJSON;
for (id element in jsonArray) {
NSLog(#"Element: %#", [element description]);
}
This code seems to come up with an error each time (ERROR 3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.)").
I'm wondering if this is a problem with the way that I'm downloading/parsing the data or if it's a problem within the actual JSON in which I have to approach it in a different matter.

Remove the &callback=results at the end of the URL. This causes the JSON to not start with an array or dictionary. Just be aware that if you are referencing "results" in your JSON code then you will need to remove/change that. If you diff the two JSON texts then you will see the difference (look at the beginning).

in a web browser open the result of the url you posted copy the contents then go to jsonlint.com and paste the contents then click validate. it shows you that the input is not valid json so you might have to do some additional parsing.

Related

JSON answer to check if a server is reachable

I have an app that just opened call a webserver page that gives me a json string.
When I'm on the local network all works without problem but when I open the app outside the local network and without vpn the app crashes.
How can I control the json string?
This is my code:
NSString *urlstr = [[NSString alloc] initWithFormat:#"%#yes.php", av];
NSURL *url = [[NSURL alloc] initWithString:urlstr];
NSError* error = nil;
NSString* urlString = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:&error];
NSString *newStr;
NSData* data=[newStr dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
sn1 = [[json objectForKey:#"Rele1"] intValue];
I want to compare the json answer with a NULL value, if the two parameters are equal I show an alert.
EDIT: If I try to read any value, the app crashes waiting the json reply...
I have bypassed the problem with an NSURLRequest with the timeoutInterval parameter that closes the connection after n seconds.
Amongst other things, you fail to:
check whether the attempt to fetch an ASCII-encoded string from a remote URL failed (obvious possibilities: the URL is unreachable, the result is UTF-8 rather than ASCII);
check whether the JSON parsing succeeds (obvious possibility: the server 404d and returned an HTML error page instead)
check whether the returned JSON object was actually a dictionary (eg, it could be an array, in which case calling objectForKey: on it will raise an exception)
The parsing of return data as ASCII then re-encoding into UTF-8 is also probably redundant — because the one supersets the other it has the effect of a threshold test, otherwise preventing acceptable results from proceeding.
Does this code ever worked?
You should check error after [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:&error];
you are reading URL data into urlString but then get NSData from uninitialized newStr and parse it?
again you should always check error whenever you provide it before anything else
why do you read the data as ASCII but the NSData as UTF8?

How To Parse JSON Format in Objective C

Hey every one i am programming an iphone app to get google search results into my app ,,, i have used the JSON Class to get the result ... when i parsed it in JSON Parser and store it in NSDictionary i got 3 keys :
responseData
responseDetails
responseStatus
the important one is the first one responseData which is has the search results ...
the problem that there is (i think) another key within responseData which is "results" which contains the urls and other stuffs which is the most important part for my app... how to access this one and put it into NSDictionary .....
this is the request :
http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=Paris%20Hilton
and to make things clear please consider to put that request into your browser and when you get the results copy it and put it in this website at the left side to see what the keys and other things:
http://json.parser.online.fr/
thnx
You could use JSON parser - SB Json to convert json string into ObjectiveC objects. Note that there are a number of JSON parsers available in ObjectiveC but I chose SB Json for it's ease of usage. But according to some benchmarks JSONKit is faster than SBJson.
Once you have your json string use this like so -
#import "JSON.h"
// Create SBJSON object to parse JSON
SBJSON *parser = [[SBJSON alloc] init];
// parse the JSON string into an object - assuming json_string is a NSString of JSON data
NSDictionary *object = [parser objectWithString:json_string error:nil];
NSLog(#"JSON data: %#", object);
Here's what you would do if you needed to parse public timeline from Twitter as JSON.The same logic could be applied to your Google Search results. You need to carefully inspect your json structure that's all...
// Create new SBJSON parser object
SBJSON *parser = [[SBJSON alloc] init];
// Prepare URL request to download statuses from Twitter
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://twitter.com/statuses/public_timeline.json"]];
// Perform request and get JSON back as a NSData object
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// Get JSON as a NSString from NSData response
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
// parse the JSON response into an object
// Here we're using NSArray since we're parsing an array of JSON status objects
NSArray *statuses = [parser objectWithString:json_string error:nil];
// Each element in statuses is a single status
// represented as a NSDictionary
for (NSDictionary *status in statuses)
{
// You can retrieve individual values using objectForKey on the status NSDictionary
// This will print the tweet and username to the console
NSLog(#"%# - %#", [status objectForKey:#"text"], [[status objectForKey:#"user"] objectForKey:#"screen_name"]);
}
Il me semble que vous savez déjà comment analyser JSON en forme NSDictionary, alors voici quelques suggestions sur la façon de forer vers le bas pour vos résultats détaillés en cascade. En anglais pour tout le monde.
responseData itself is an NSDictionary and results is an object within it. Results happens to be an array for the case you gave.
After you convert the JSON to NSDictionary form, you will have recursively converted all of the objects inside.
You might try something like this to get at what you are looking for:
Lets assume the the fully converted JSON is in a NSDictionary called response
NSDictionary *responseDate = [response objectForKey:#"responseData"];
NSArray *resultsArray = [responseData objectForKey:#"results"];
Now you can use an iterator or a for-loop to go through each result.
One word of caution is that if there is only one result, you should first test to see if the class of the object is NSArray. Also, if there are no results, you should test for that too.
So you may want to code it this way to handle these cases:
NSDictionary *responseDate = [response objectForKey:#"responseData"];
If ([[responseData objectForKey:#"results"] isKindOfClass [NSArray class]]) {
NSArray *resultsArray = [responseData objectForKey:#"results"];
... do other things to get to each result in the array ...
}
else if ([[responseData objectForKey:#"results"] isKindOfClass [NSDictionary class]]) {
// it looks like each individual result in returned in a NSDictionary in your example
... do the things to handle the single result ...
}
else {
// handle no results returned
}
The first thing you should do, if you do not understand exactly what's going on, is to NSLog the description of the JSON parser output. This will be a "nest" of NSDictionary and NSArray, and when you see the description output you will understand that there is a one-to-one mapping of JSON "object" to NSDictionary and JSON "array" to NSArray. So you "understand" the parser output the same way you "understand" the JSON source.
In your case you'd likely extract the "responseData" object, cast it to an NSDictionary, extract "results" from that, cast it (guessing here) to an NSArray, then iterate through that array to extract your individual results.

Sending string via ftp : getting error

I'm trying to send a string via ftp using the code below but I'm getting an error:
{
//miscellaneous lines of code.....
//Convert contents of shopping cart into a property list
[Cart serializeCart];
//now need to transport the propertyList to the webserver
//first step is get the serialized propertylist from the documents folder
NSString *pathToSerializedCart = [rootPath stringByAppendingPathComponent:#"serializedCart.plist"];
NSString *shoppingCartString;
if (![fileManager fileExistsAtPath:pathToSerializedCart])
{
NSLog(#"ERROR:\nCouldnt find serialized cart in documents folder.");
}
else
{
NSData *serializedData = [NSData dataWithContentsOfFile:pathToSerializedCart];
shoppingCartString = [[NSString alloc] initWithData:serializedData encoding:NSUTF8StringEncoding];
}
NSLog(#"%#", shoppingCartString);
//Now that the cart is converted into a string. it is ready for transport
NSURL *url = [NSURL URLWithString:#"ftp://username:password#domainName.com/folder/serializedCart.xml"];
BOOL OK =[shoppingCartString writeToURL:url atomically:NO encoding:NSUTF8StringEncoding error:&error];
if(!OK) {
NSLog(#"Error writing to file %# , error = %#", url, [error localizedFailureReason]);
}
I'm getting the following console output for this code:
Error writing to file ftp://username:password#domainName.com/folder/serializedCart.xml , error = (null)
One of the variables: _domain in this error object in the last line when, I mouse over it during debugging says NSCocoaErrorDomain
I'm not sure how to debug this.
Could someone give any suggestions?
The writeToURL:.. methods don't support the FTP protocol. You'll have to use other mechanisms to write the string content onto an ftp server. You can look at tools such as ios-ftp-server to handle such uploads. You can also look at this sample code from Apple.

how to pass xml results to core data object

How do you pass a list of words that are in xml format to a "core data" database?
And from that, each time your application loads how do you check to see if that database is up to date?
You will need to parse the incoming XML as string. If you are on a mac use NSXMLDocument... try something like this:
NSString *yourXML = #""; // replace with your xml as nsstring
NSError *error;
NSXMLDocument *xmlDoc = [[NSXMLDocument alloc] initWithXMLString:yourXML options:0 error:&error];
if (error) NSLog(#"Error parsing xml: %#", [error description]);
And then you could parse every item you are interested in using an XPath query like this:
NSArray *items = [xmlDoc nodesForXPath:#"//yourItem" error:&error];
And then you could likewise loop every single item for its properties in xml format.
Then fetch an item according to one or more key properties you have in your xml and check if they are already there.
I suggest you take a look at this post http://objectivesheep.com/archive/core-data-active-record-sheepdata/ for an easier way to manage your core data objects. In that case you would simply have something like:
if ([YourManagedObject checkIfEntityExistsWhereProperty:#"yourKeyProperty" equalsValue:keyValueFromXML]) ....
Hope this helps.

Failing to parse JSON... is the encoding messed up?

I am trying to parse the JSON returned here: http://www.waterwayguide.com/map/php/bridge.php?ll=25.514339,-80.076164
However, I can't parse it as I normally would it seems:
NSData *jsonData = [[(ASIHTTPRequest*)[data objectForKey:#"request"] responseString] dataUsingEncoding:NSUTF32BigEndianStringEncoding];
NSLog(#"this prints as expected %#", [(ASIHTTPRequest*)[data objectForKey:#"request"] responseString]);
NSArray* jsonNodes = [[CJSONDeserializer deserializer] deserialize:jsonData error:&error];
NSLog(#"this is unexpectedly nil %#", jsonNodes);
I have used this precise code on a different JSON feed and it works nicely. Is there something I can do on the client side to parse this feed properlY?
That feed isn't JSON. Look at the source. It's text/html and it doesn't validate because it attempts to escape ' with \'. Altogether, it seems to be a quick attempt to manually output JSON instead of HTML.