Convert JSON feed to NSDictionary - ios

Where JSON_CATEGORY_DATA_URL_STRING is my feed URL, which returns fine as:
[
{
"group":"For Sale",
"code":"SSSS"
},
{
"group":"For Sale",
"category":"Wanted",
"code":"SWNT"
}
]
I cannot seem to get a nice NSDictionary (or NSArray) out of the following code:
+ (NSDictionary *)downloadJSON
{
NSDictionary *json_string;
NSString *dataURL = [NSString stringWithFormat:#"%#", JSON_CATEGORY_DATA_URL_STRING];
NSLog(#"%#",dataURL);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:dataURL]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
json_string = [[[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]autorelease];
NSDictionary *json_dict = (NSDictionary *)json_string;
NSLog(#"json_dict\n%#",json_dict);
NSLog(#"json_string\n%#",json_string);
return json_string;
}
I've read many posts on this, but am not getting it.

With IOS5 you can use NSJSONSerialization for serializing the JSON.
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

You can't just cast a string as a dictionary and expect it to parse the JSON. You must use a JSON parsing library to take that string and convert it into a dictionary.

I made a class that makes this task easier. It uses iOS 5's NSJSONSerialization. Clone it from github here.

You need to use JSON parser. here is the edited code
+ (NSDictionary *)downloadJSON
{
NSDictionary *json_string;
NSString *dataURL = [NSString stringWithFormat:#"%#", JSON_CATEGORY_DATA_URL_STRING];
NSLog(#"%#",dataURL);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:dataURL]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
json_string = [[[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]autorelease];
//JSONValue is a function that will return the appropriate object like dictionary or array depending on your json string.
NSDictionary *json_dict = [json_string JSONValue];
NSLog(#"json_dict\n%#",json_dict);
NSLog(#"json_string\n%#",json_string);
return json_dict;
}
this should be the code to get the NSDictionary. but you json string is an array so instead use .
+ (NSArray *)downloadJSON
{
NSDictionary *json_string;
NSString *dataURL = [NSString stringWithFormat:#"%#", JSON_CATEGORY_DATA_URL_STRING];
NSLog(#"%#",dataURL);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:dataURL]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
json_string = [[[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]autorelease];
NSArray *json_dict = [json_string JSONValue];
NSLog(#"json_dict\n%#",json_dict);
NSLog(#"json_string\n%#",json_string);
return json_dict;
}
Edit:
you need to use JSON.framework to call JSONValue method.
also you need to return json_dict instead of json_string as json_string is of NSString type and not NSDictionary or NSArray.
and dont autorelease it, as it is your class variable

create method to fetchjson data.Pass your url in urlwithstring.
-(void)fetchjsondata
{
NSString *login= [[NSString stringWithFormat:#"your url string"]stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"----%#", login);
NSURL *url = [NSURL URLWithString:[login stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
//-- Get request and response though URL
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (data) {
dic_property= [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(#"%#", dic_property);
NSLog(#"counts=%d",[[dic_property objectForKey:#"Data"]count]);
}
else {
NSLog(#"network error, %#", [error localizedFailureReason]);
}
});
}];
}
call fetchjsonmethod in anywhere.
[NSThread detachNewThreadSelector:#selector(fetchdata) toTarget:self withObject:nil];

Related

Adding Rotten Tomates API to iphone app

Im trying to add Rotten Tomatoes API to my app but it doesn't seem to like it? What am I doing wrong?? The error says "Data Argument not used by format string"
-(void)main {
NSLog(#"Service has run");
NSString *api_key = #"j4jz49tvf76cmnb4mwfyjvyt";
NSString *search_term = [searchTerm stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSString *url = [NSString stringWithFormat:#"http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json?limit=16&country=us&apikey=j4jz49tvf76cmnb4mwfyjvyt", api_key, search_term];
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSData *responseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil];
if (responseData !=nil) {
NSError *error =nil;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions error:&error];
if (error) {
[delegate serviceFinished:self withError:YES];
} else {
results = (NSArray *) [json valueForKey:#"movies"];
[delegate serviceFinished:self withError:NO];
}
} else {
[delegate serviceFinished:self withError:YES];
}
}
#end
Your error is on this line
NSString *url = [NSString stringWithFormat:#"http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json?limit=16&country=us&apikey=j4jz49tvf76cmnb4mwfyjvyt", api_key, search_term];
String with format works with adding a data argument like %# in a string as a placeholder, and then replacing that with the following arguments in your method call.
What you want to do is probably something like:
NSString *url = [NSString stringWithFormat:#"http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json?limit=16&country=us&apikey=%#&search_term=%#", api_key, search_term];

French accents on cell.detailTextLabel in UITableView (Objective-C)

I have a problem I can't deal with.
In my application, I get datas from my Web Service in JSON. It's UTF8-encoded and when I fill an UITableView everything is ok (NSLog return accents like : "\u00e9" but my UITableView shows it like : "é").
But when I set the same data in my detailTextLabel, it doesn't convert "\u00e9" to "é" ...
Tried some tricks with encoding, but nothing convincing.
Parsing methods :
- (NSDictionary*)fetchedData:(NSData *)responseData {
NSError* error;
self.json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
return self.json;
}
-(void)executeParsingWithUrl:(NSURL*)anUrl{
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:anUrl];
NSString *authStr = [NSString stringWithFormat:#"%#:%#",[[NSUserDefaults standardUserDefaults] stringForKey:#"username_ws"], [[NSUserDefaults standardUserDefaults] stringForKey:#"password_ws"]];
NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [Base64 encode:authData]];
[urlRequest setValue:authValue forHTTPHeaderField:#"Authorization"];
NSError *requestError = NULL;
NSHTTPURLResponse *response = NULL;
NSData *responseData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&requestError];
[self performSelectorOnMainThread:#selector(fetchedData:)
withObject:responseData waitUntilDone:YES];
}
Recuperation :
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
JsonParsing *getJson = [[JsonParsing alloc] init];
[getJson executeParsingWithUrl: leUrl];
self.duration = [NSString stringWithFormat:#"%#",[[getJson.json objectForKey:#"objects"]valueForKey:#"libel"]];
});
Thanks in advance !
I managed it thanks to other people.
I my cell.detailTextLabel I used this :
cell.detailTextLabel.text = [NSString stringWithCString:[myText cStringUsingEncoding:NSUTF8StringEncoding] encoding:NSNonLossyASCIIStringEncoding];

JSON parsing in iOS 6 issues

I am trying to parse some values from a json. I manage to get the value for results.geometry.location. If the parameters fails the server return a json with 2 value. results which is empty[] and status "some error".
url = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?address=%#&sensor=false",postalCode];
NSData *jsonDataString = [[NSString stringWithContentsOfURL:[NSURL URLWithString:url] encoding:NSUTF8StringEncoding error: nil] dataUsingEncoding:NSUTF8StringEncoding];
NSArray* myResults = [NSJSONSerialization JSONObjectWithData:jsonDataString options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:&error];
latLon =[myResults valueForKeyPath:#"results.geometry.location"];
generalDict = (NSDictionary *)[latLon objectAtIndex:0];
NSLog(#"%#",[generalDict objectForKey:#"lat"]);
It's confusing. I tried:
latLon =[myResults valueForKeyPath:#""];
generalDict = (NSDictionary *)[latLon objectAtIndex:0];
NSLog(#"%#",[generalDict objectForKey:#"status"]);
but is not working. How can I get the value of the status. This is how it looks like when the request is invalid:
{
"results" : [],
"status" : "ZERO_RESULTS"
}
myResults is a dictionary, not an array. I think you want something like this:
NSURL *url = [NSURL urlWithString:[NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?address=%#&sensor=false",postalCode];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSDictionary *jsonPayload = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves
error:nil];
NSString *status = [jsonPayload objectForKey:#"status"];
//Check for error status
NSArray *resultsArray = [jsonPayload objectForKey:#"results"];
//Do whatever you want with your results array
}];

How to load images from ftp? [iOS]

There are, for example, 100 JSON files and appropriate 100 images on my ftp server.
1.With loading JSON where are no bug (I hope)
NSString *recipesPath = #"ftp://.../recipes/";
NSString *recipeFileName = [NSString stringWithFormat:#"00001.json", recipeCode];
NSString *recipeFileFullPath = [recipesPath stringByAppendingString:recipeFileName];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:recipeFileFullPath]];
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSError *error = nil;
NSDictionary *recipeDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
2.But images can not be loaded
NSString *recipeImageName = #"recipeImages/00001-1.jpg";
NSString *recipeImageFullPath = [recipesPath stringByAppendingString:recipeImageName];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:recipeImageFullPath]];
if (request) {
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
if (responseData) {
UIImage *image = [UIImage imageWithData:responseData];
}
}
responseData nearly always is nil.
May be there is the other method?
All this code is in MyMethod which I execute in NSOperationQueue:
operation = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(MyMethod) object:nil];
[operationQueue addOperation:operation];
EDIT: image sizes are not big - from 50 to 100 kbyte
EDIT: can image file extension affect to downloading process?
You can try this:
NSURL *url = [NSURL URLWithString:recipeImageFullPath];
NSData *data = [NSData alloc] initWithContentsOfURL:url];
Please try to test it:
NSError *requestError;
NSURLResponse *urlResponse = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
/* Return Value
The downloaded data for the URL request. Returns nil if a connection could not be created or if the download fails.
*/
if (responseData == nil) {
// Check for problems
if (requestError != nil) {
...
}
}
else {
// Data was received.. continue processing
}

ios parsing json result after http request

am starting to build login form reading from external server via http request i need to parse json result to get user name
- (IBAction)getlogin:(UIButton *)sender {
NSString *rawStrusername = [NSString stringWithFormat:#"username=%#",_username.text];
NSString *rawStrpassword = [NSString stringWithFormat:#"password=%#",_password.text];
NSString *post = [NSString stringWithFormat:#"%#&%#", rawStrusername, rawStrpassword];
// NSString *post = #"rawStrusername&rawStrpassword";
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
/* NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]]; */
NSURL *url = [NSURL URLWithString:#"http://www.othaimmarkets.com/my_services_path/user/login.json"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
/* [request setValue:postLength forHTTPHeaderField:#"Content-Length"]; */
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSLog(#"responseData: %#", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]);
//NSLog(#"responseData: %#", responseData);
}
I get this result:
{"sessid":"g2ev7til6d750ducrkege0cbj2","session_name":"SESS02795057fe9e6b2fc0777bf4057b248f","user":{"uid":"617","name":"mohammed.abdelrasoul#gmail.com","mail":"mohammed.abdelrasoul#gmail.com","mode":"0","sort":"0","threshold":"0","theme":"","signature":"","signature_format":"0","created":"1316602317","access":"1352643854","login":"1352666338","status":"1","timezone":"10800","language":"ar","picture":"","init":"mohammed.abdelrasoul#gmail.com","data":"a:5:{s:18:\"country_iso_code_2\";s:2:\"SA\";s:13:\"timezone_name\";s:11:\"Asia/Riyadh\";s:5:\"block\";a:1:{s:7:\"webform\";a:1:{s:15:\"client-block-88\";i:1;}}s:13:\"form_build_id\";s:37:\"form-3ae73833f08accc7abe5517347ea87eb\";s:7:\"contact\";i:0;}","country_iso_code_2":"SA","timezone_name":"Asia/Riyadh","block":{"webform":{"client-block-88":1}},"form_build_id":"form-3ae73833f08accc7abe5517347ea87eb","contact":0,"roles":{"2":"authenticated user"}}}
Or, formatted for the sake of legibility:
{
"sessid":"g2ev7til6d750ducrkege0cbj2",
"session_name":"SESS02795057fe9e6b2fc0777bf4057b248f",
"user":{
"uid":"617",
"name":"mohammed.abdelrasoul#gmail.com",
"mail":"mohammed.abdelrasoul#gmail.com",
"mode":"0",
"sort":"0",
"threshold":"0",
"theme":"",
"signature":"",
"signature_format":"0",
"created":"1316602317",
"access":"1352643854",
"login":"1352666338",
"status":"1",
"timezone":"10800",
"language":"ar",
"picture":"",
"init":"mohammed.abdelrasoul#gmail.com",
"data":"a:5:{s:18:\"country_iso_code_2\";s:2:\"SA\";s:13:\"timezone_name\";s:11:\"Asia/Riyadh\";s:5:\"block\";a:1:{s:7:\"webform\";a:1:{s:15:\"client-block-88\";i:1;}}s:13:\"form_build_id\";s:37:\"form-3ae73833f08accc7abe5517347ea87eb\";s:7:\"contact\";i:0;}",
"country_iso_code_2":"SA",
"timezone_name":"Asia/Riyadh",
"block":{
"webform":{
"client-block-88":1
}
},
"form_build_id":"form-3ae73833f08accc7abe5517347ea87eb",
"contact":0,
"roles":{
"2":"authenticated user"
}
}
}
how i can get the objects data or parse the result to get user name
any help or examples will be appreciated
You need to use the NSJSONSerialization class method, JSONObjectWithData:options:error: to create an NSDictionary:
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];
if (! error) {
NSLog(#"%#",jsonDict);
}else{
NSLog(#"%#",error.localizedDescription);
}
This will get you to the point where you can look at the dictionary, which will be easier to read. It looks like you need to use objectForKey:#"sessid" to get you to user, then objectForKey#"user", then objectForKey:#"name" to get you to the name.
Check out this framework for parsing json. https://github.com/stig/json-framework/
Also check out this answer iPhone/iOS JSON parsing tutorial. You'll find a link to a tutorial you can do to get acquainted with json parsing in ios.
See this answer and some code :
NSMutableData *data; // Contains data received from the URL connection declares in header
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)dataIn
{
// Do it this way because connection doesn't guarantee all the data is in
POLLog(#" Tide View connection");
[data appendData:dataIn];
}
- (void) connectionDidFinishLoading:(NSURLConnection *) conn
{
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *results = [jsonString JSONValue]; // This is a new category added to the NSString by SBJSON
//100 parameters
for (int n=0;n<=100;n++)
{
// Get all the returned results
params[n] = [[results objectForKey:[NSString stringWithFormat:#"param%d",n]] floatValue];
}
To expand upon rdelmar's answer (which I think you should accept), you can use NSJSONSerialization and then navigate the NSDictionary results to extract the userName:
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:responseData
options:0
error:&error];
if (error == nil) {
NSDictionary *userDictionary = [jsonDict objectForKey:#"user"];
NSString *userName = [userDictionary objectForKey:#"name"];
// do what you need with the userName
} else {
NSLog(#"%#",error.localizedDescription);
}
Or if using the latest version of Xcode, you can replace those objectForKey references with the even more concise Modern Objective-C syntax:
NSDictionary *userDictionary = jsonDict[#"user"];
NSString *userName = userDictionary[#"name"];

Resources