no returns in NSJSONSerialization - iphone

Could you please forgive me for eventual mistakes i can make asking this question me it's my first one here.
After reading several topics on this website, like this one first i'll try to use the describe methods but it still doesn't work # all :-(
My .json file looks like this
{ "speakers" :
[
{
"name":"Value",
"picture": "URL VALUE",
"business":"VALUE",
"desc":"VALUE",
"twitter": "URL VALUE"
}
{
...
}
]
}
So this is my reasoning :
I firstly have a dictionary which contains speaker attribute
This one contains an array, field by some dictionnaries within "name", "business",... attr.
So, this is my obj-C code :
NSString *URLStr = #"URLofMyJsonFile";
NSURLRequest *JSONRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithString:URLStr ]]];
NSData *JSONData = [NSURLConnection sendSynchronousRequest:JSONRequest returningResponse:nil error:nil];
NSError *parsingError = nil;
NSDictionary *speakerDictionnary = [NSJSONSerialization JSONObjectWithData:JSONData options:0 error:&parsingError];
NSArray *speakersArray = [speakerDictionnary objectForKey:#"news"];
for (NSDictionary *oneSpeaker in speakersArray) {
NSLog(#"The speakers's name is %#", [oneSpeaker objectForKey:#"name"]);
NSLog(#"The speakers's business is %#", [oneSpeaker objectForKey:#"business"]);
NSLog(#"The speakers's desc is %#", [oneSpeaker objectForKey:#"desc"]);
}
EDIT : I remplace the right URL of my Script with Dummy

Your JSON isn't valid, there needs to be a comma between the individual speaker dictionaries.
{ "speakers" :
[
{
"name":"Value",
"picture": "URL VALUE",
"business":"VALUE",
"desc":"VALUE",
"twitter": "URL VALUE"
} <=== MISSING COMMA HERE
{
...
}
]
}

As omz mentioned the json is wrong. you can try below code :
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.appios.fr/client/takeoff/app/script/jsonSpeaker.json"]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *reponse,NSData *data,NSError *error){
if (!error) {
NSError *jsonError;
id json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
NSArray *speakersList = [json objectForKey:#"speakers"];
[speakersList enumerateObjectsUsingBlock:^(NSDictionary *dict,NSUInteger idx,BOOL *Stop){
NSLog(#"Name : %#",[dict objectForKey:#"name"]);
}];
}
} ];

Related

JSONKit giving parse error but JSONLint.org says it's valid

Here's my post.json file:
[
{
"Title": "Introduction to WCF",
"Url": "http://myaddress/videos/introduction-to-wcf",
"Thumbnail": "http://myaddress/images/20110212_01.jpg",
"Exceprt": "Introduction to WCF",
"PostDate": "2011-02-12T14:26:07",
"Id": 39,
"Mp4Video": "http://myaddress/2012/05/20110212_01.mp4",
"Speakers": [
{
"Name": "Mark Wilkinson",
"Slug": "mark-wilkinson"
}
],
"Groups": [
{
"Name": "C# UG",
"Slug": "cs-ug"
}
],
"Tags": [
{
"Name": "WCF Services",
"Slug": "wcf-services"
}
]
}
]
post this in jsonlint.org and it validates.
Here's the code that I've been using for other JSON files that has worked:
- (void)test_can_read_from_groups_file_and_build_JSONDictionary {
id result = [self data_from_JSON_file:#"post"];
[Assert isNotNil:result]; // is returning as nil, so test is failing
}
- (id)data_from_JSON_file:(NSString *)fileName {
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *jsonString = [bundle pathForResource:fileName ofType:#"json"];
NSData *data = [NSData dataWithContentsOfFile:jsonString];
JSONDecoder *decoder = [[JSONDecoder alloc] initWithParseOptions:JKParseOptionNone];
NSError *error = nil;
id result = [decoder objectWithData:data error:&error];
if (error) {
NSLog(#"*********\r\r\r\r\r\r\r Error was: %#", [error localizedDescription]);
}
return result;
}
error that is printed out from JSONKit objectWithData:
Error was: Unexpected token, wanted '{', '}', '[', ']', ',', ':', 'true', 'false', 'null', '"STRING"', 'NUMBER'.
ETA: yes it's in the build phases:
added:
if (!data)
{
NSLog(#"\r\r\r\r\r\r%s: data was nil", __FUNCTION__);
return nil;
}
It's not hitting this branch so data is not nil.
Changed using JSONKit decoder to this:
id results = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions error:&error];
and it works, still perplexed as to why JSONKit is failing for me but not for Rob.
As pst pointed out, the problem turned out to be the BOM. In Xcode, if you right-click on the filename, choose "Open As" and choose "Hex", you'll see:
Those first three characters are obviously not standard text characters. Fortunately, you can highlight these three characters in the hex editor in Xcode, delete them, save the file, and it will now that should fix it.
Original answer:
Also, are you sure the JSON was included in your bundle (check "Copy Bundle Resources" in the "Build Phases" of your "Target Settings). I just parsed your JSON with Cocoa standard JSON parsing class, NSJSONSerialization, without incident. Perhaps you should try examining the data and make sure everything is ok:
NSLog(#"data=%#", [[[NSString alloc] initWithData:data] autorelease]);
But I parsed your JSON with both JSONKit and NSJSONSerialization without incident.
NSString *filename = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"json"];
NSData *data = [NSData dataWithContentsOfFile:filename];
if (!data)
{
NSLog(#"%s: data was nil", __FUNCTION__);
return;
}
JSONDecoder *decoder = [[JSONDecoder alloc] initWithParseOptions:JKParseOptionNone];
NSError *error = nil;
id results = [decoder objectWithData:data error:&error];
// Also tested with NSJSONSerialization
//
// id results = [NSJSONSerialization JSONObjectWithData:data
// options:0
// error:&error];
if (!error)
NSLog(#"%s: results = %#", __FUNCTION__, results);
else
NSLog(#"%s: error = %#", __FUNCTION__, error);

How to parse json data with "var abcd =" header

I'm having problem with parsing json data file on iOS.
This is a sample from the data.json file:
var devs = [
{
"ident":"1",
"firstname":"Jan",
"lastname":"Kowalski",
"img":"http://www.placekitten.com/125/125",
"tech":"iOS, HTML5, CSS, RWD",
"github":"placeholder",
"opensource":"1",
"twitter":"placeholder"
},
{
"ident":"2",
"firstname":"WacĹaw",
"lastname":"GÄsior",
"img":"http://www.placekitten.com/124/125",
"tech":"Android, Java, Node.js",
"github":"GÄsiorBKR",
"twitter":"wacek5565"
},
and so on.
With "normal" json files I use:
NSURLResponse *response;
NSError *myError;
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://somerailsapplication/posts.json"] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30.0f];
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&myError];
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&myError];
Unfortunately this solution doesn't work in this case.
Is there any chance to get this working without searching for specific string "var dev=[" and the last "]" in the downloaded data?
The response is javascript, not JSON, so you won't be able to use a JSON parser directly. If you can't change the server output, the easiest thing would be to strip the beginning and end of the data, as you suggested. You could also embed the response in an HTML template and evaluate it in a webview, but that seems like a lot of more work.
Starting at the point where you've got the data:
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&myError];
NSMutableString *dataAsString = [[NSMutableString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[dataAsString deleteCharactersInRange:NSMakeRange(0, 11)];
data = [dataAsString dataUsingEncoding:NSUTF8StringEncoding];
NSArray *res = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&myError];
This turns the data into a string, removes the first 11 characters, turns it back into data, and then parses it as normal. (I've changed it to NSArray since your data is in an array)

AFJSONRequestOperation crashing with "data parameter is nil" NSJSONSerialization error

I previously asked a similar question on this but didn't get much help and have now looked into it further and still can't see why I have a problem.
NSURL *url = [NSURL URLWithString:#"http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json/sitelist?res=daily&key=<MY API KEY>"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(#"Success");
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Fail");
}];
[operation start];
This fails with the following
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'
I believe the problem is due to the JSON type returned as ISO-8859-1, I managed to get this working with NSJSONSerialization by encoding the retuned string to NSUTF8StringEncoding
Example...
NSString *string = [NSString stringWithContentsOfURL:kMetOfficeAllSites encoding:NSISOLatin1StringEncoding error:&error];
NSData *metOfficeData = [string dataUsingEncoding:NSUTF8StringEncoding];
id jsonObject = [NSJSONSerialization JSONObjectWithData:metOfficeData options:kNilOptions error:&error];
if (error) {
//Error handling
} else {
//use JSON
So I looked at responseJSON in AFJSONRequestOperation.m
- (id)responseJSON {
[self.lock lock];
if (!_responseJSON && [self.responseData length] > 0 && [self isFinished] && !self.JSONError) {
NSError *error = nil;
// Workaround for behavior of Rails to return a single space for `head :ok` (a workaround for a bug in Safari), which is not interpreted as valid input by NSJSONSerialization.
// See https://github.com/rails/rails/issues/1742
if ([self.responseData length] == 0 || [self.responseString isEqualToString:#" "]) {
self.responseJSON = nil;
} else {
// Workaround for a bug in NSJSONSerialization when Unicode character escape codes are used instead of the actual character
// See http://stackoverflow.com/a/12843465/157142
NSData *JSONData = [self.responseString dataUsingEncoding:self.responseStringEncoding];
self.responseJSON = [NSJSONSerialization JSONObjectWithData:JSONData options:self.JSONReadingOptions error:&error];
}
self.JSONError = error;
}
[self.lock unlock];
return _responseJSON;
}
The code is crashing in the else statement, however this seems to be doing what I was doing previously when using NSJSONSerialization directly and re-encoding the responseString.
I even hardcoded dataUsingEncoding to NSUTF8StringEncoding but it still crashes and I don't understand why?
Note: The above works fine with other JSON feeds, also from other feeds on
http://datapoint.metoffice.gov.uk/ but
http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json/sitelist?res=daily&key=
includes the place name Sóil Chaorainn which causes the problem
The problem seems to be that the text encoding of the response is wrong. There are characters that can't be encoded using ISO-8859-1. This is why the responseString method (see AFURLConnectionOperation.m) returns nil and the JSON serialization fails.
To solve the issue you could subclass AFJSONRequestOperation and override responseStringEncoding in this way to enforce UTF-8 encoding:
- (NSStringEncoding)responseStringEncoding {
[self.lock lock];
if (!_responseStringEncoding && self.response) {
self.responseStringEncoding = NSUTF8StringEncoding;
}
[self.lock unlock];
return _responseStringEncoding;
}

iPhone: Formatting Json params using third party parser

I want to create JSON object params for example below. I had worked on iOS 5 devices and could able to achieve this using NSJSONSerialization API. For example, i created a generic function "makeJSONObject()" and using for it.
Sample Payload 1:
{
token: "kjsdfjl23kkj23kk"
entries: [
{
"title": "welcome",
"name": "myself",
"date": "2012-02-06T00:14:20Z",
},{
"title": "Hi",
"name": "martin",
"date": "2012-02-06T00:14:20Z",
}
]
}
Sample Payload 2:
{
"email" : "me#company.com",
"password" : "pswrd"
}
CODE:
NSString *jsonRequest = [appDelegate makeJSONObject:[NSArray arrayWithObjects: emailStr, passwordStr, nil] :[NSArray arrayWithObjects: #"email", #"password", nil] ];
-(NSString *) makeJSONObject :(NSArray *)objects :(NSArray *)keys
{
NSString *theBodyString = NULL;
NSDictionary *data = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
//NSLog(#"data: %#", data);
NSError *writeError = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:NSJSONWritingPrettyPrinted error:&writeError];
theBodyString = [[NSString alloc] initWithData:jsonData encoding:NSASCIIStringEncoding];
return theBodyString;
}
But, i want to support now for 4.0 devices, and i can't use NSJSONSerialization API now. I may have to use SBJson or something like that i guess and i have no idea. Could someone help me how can i modify my generic function above to make use of
SBJson or some third party parser classes?
Please help! Thank you.
NSString *jsonRequest = [NSString stringWithFormat:#"&json_data=%#",[[NSString stringWithFormat:#"{\"listInvoice\":{\"client_id\":\"\",\"date_from\":\"\",\"date_to\":\"\",\"invoice_number\":\"\",\"invoice_record_status\":\"\",\"invoice_status\":\"\",\"page\":\"1\",\"per_page_record\":\"20\"}}"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
Try my extension for NSArray/NSDictionary for building JSON strings from these basic data types.
https://github.com/H2CO3/CarbonateJSON

How to get user account information from Twitter using objective-c?

i have used oauth mechanism to let the user login via twitter in my app, on successful login it returns me the access taken, username and oauth_token_secret, i want to get the user account information from twitter like his location, date of birth, and other profile information. I have searched the Rest Api given on the twitter's official site but haven't found any such link.... so how to get the user 's account information? kindly help me.
what about this call
https://api.twitter.com/1/users/show.json?screen_name=TwitterAPI&include_entities=true
Twitter-Kit Version 3.4.0 Here is function
-(void)userVerify:(NSString *)userID{
NSString *statusesShowEndpoint = #"https://api.twitter.com/1.1/users/show.json";
NSDictionary *params = #{#"id": userID};
NSError *clientError;
// Objective-C
TWTRAPIClient *client = [[TWTRAPIClient alloc] init];
NSURLRequest *request = [client URLRequestWithMethod:#"GET" URLString:statusesShowEndpoint parameters:params error:&clientError];
if (request) {
[client
sendTwitterRequest:request
completion:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
if (data) {
// handle the response data e.g.
NSError *jsonError;
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:data
options:0
error:&jsonError];
NSLog(#"%#",[json description]);
self.txtViewDetails.text = [json description];
}
else {
NSLog(#"Error code: %ld | Error description: %#", (long)[connectionError code], [connectionError localizedDescription]);
self.txtViewDetails.text = [NSString stringWithFormat:#"Error code: %ld | Error description: %#", (long)[connectionError code], [connectionError localizedDescription]];
}
}];
}
else {
NSLog(#"Error: %#", clientError);
}
}