I have seen that most data in iOS is in either JSON or XML. I was interested to know whether there is any third party library or wrapper class that tackles both types of data and responses accordingly. I know I could use for example JSONKit for JSON data and NSXMLParser for XML. But i looking for one that tackles both.
Is there any such wrapper?
Welcome to any suggestions and guidance. Thanks.
I think It's support to JSON /XML,just can you change some line.
NSString *str1=#"type url";
NSString *poststr1 = [NSString stringWithFormat:#"%#",str1];
NSString *posturl1=[NSString stringWithFormat:#" your url json/xml"];
// NSLog(#"city url name %#",posturl1);
NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:#"%#",posturl1]];
NSData *postData1 = [poststr1 dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData1 length]];
NSMutableURLRequest *request =[[[NSMutableURLRequest alloc] init] autorelease];
[request setHTTPBody:postData1];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSError *error;
NSURLResponse *response;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
// NSString *data=[[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];//this line supprted to json
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:urlData
options:kNilOptions
error:&error];//this line supported to xml
NSLog(#"json %#",json);
//NSDictionary*results = [data JSONValue];//this line supported to JSON
//NSLog(#"results json----->%#",results);
AFNetworking will do both, and has a goot reputation, for example see the Ray Wenderlich site which has lots of other useful information too.
I have created one wrapper class for json. In there, I have created one method given below, I think it will help you.
Parse Method:
-(void)jsonDeserialize:(NSString *)key fromDict:(id)content completionHandler:(void (^) (id parsedData, NSDictionary *fromDict))completionHandler{
if (key==nil && content ==nil) {
completionHandler(nil,nil);
}
if ([content isKindOfClass:[NSArray class]]) {
for (NSDictionary *obj in content) {
[self jsonDeserialize:key fromDict:obj completionHandler:completionHandler];
}
}
if ([content isKindOfClass:[NSDictionary class]]) {
id result = [content objectForKey:key];
if ([result isKindOfClass:[NSNull class]] || result == nil) {
NSDictionary *temp = (NSDictionary *)content;
NSArray *keys = [temp allKeys];
for (NSString *ikey in keys) {
[self jsonDeserialize:key fromDict:[content objectForKey:ikey] completionHandler:completionHandler];
}
}else{
completionHandler(result,content);
}
}
}
Method Call:
NSData *content = [NSData dataWithContentsOfFile:[[NSBundle mainBundle]pathForResource:#"Sample" ofType:#"json"]];
NSError *error;
//to get serialized json data...
id dictionary = [NSJSONSerialization JSONObjectWithData:content options:NSJSONReadingMutableContainers error:&error];
//get data for key called GetInfo
[self jsonDeserialize:#"GetInfo" fromDict:dictionary completionHandler:^(id parsedData, NSDictionary *fromDict) {
NSLog(#"%# - %#",parsedData,fromDict);
}];
Related
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];
FIRST EDIT:
I put returnData in JSONObjectWithData:options:error but the error persists.
The problem happens 1 in 10 times, but it's annoying because the application does not work.
2014-02-18 10:26:03.236 finalAbogados[47279:f803] Error en consulta basica: Error Domain=NSCocoaErrorDomain Code=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.) UserInfo=0x686c330 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
im doing an APP on iOS that get a JSON object from a PHP Script.
The script calls data from data base in MS SQL and encode these data in a JSON Object. Then i get the object on iOS and i use NSJSONSerialize for handle data.
The problem is, sometimes I get a null value and sometimes I get the array correctly. The data returned me the script is always the same, expose here:
[{"0":"","NombreOrganismo":"","1":"Judicial","NombreTipoInstancia":"Judicial","2":"(Sin asignar)","Numero":"(Sin asignar)"}]
The code that performs the query and the data in question is:
NSString *myRequestString = [NSString stringWithFormat:#"user=%#&pass=%#&cod_asunto=%#", u_received, p_received, cod_received];
NSData *myRequestData = [NSData dataWithBytes: [myRequestString UTF8String] length: [myRequestString length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString:#""]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"content-type"];
[request setHTTPBody:myRequestData];
NSURLResponse *response;
NSError *error;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *content = [NSString stringWithUTF8String:[returnData bytes]];
NSData *jsondata = [content dataUsingEncoding:NSUTF8StringEncoding];
NSError *jsonError = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:jsondata options:kNilOptions error:&jsonError];
NSMutableArray *NombreOrga = [[NSMutableArray alloc] init];
NSMutableArray *NombreInstancia = [[NSMutableArray alloc] init];
NSMutableArray *Numero = [[NSMutableArray alloc] init];
if ([jsonObject isKindOfClass:[NSArray class]]) {
NSLog(#"Its an ARRAY!!.");
NSArray *jsonArray = (NSArray *)jsonObject;
for (id item in jsonArray) {
if ([item isKindOfClass:[NSDictionary class]]) {
NSString *aux = [(NSDictionary*)item objectForKey:#"NombreOrganismo"];
NSString *aux2 = [(NSDictionary*)item objectForKey:#"Numero"];
NSString *aux3 = [(NSDictionary*)item objectForKey:#"NombreTipoInstancia"];
if (aux) {
[NombreOrga addObject:aux];
}
if (aux2) {
[NombreInstancia addObject:aux2];
}
if (aux3) {
[Numero addObject:aux3];
}
} else {
NSLog(#"item %# is not a dictionary",item);
}
}
}
else {
NSLog(#"Its probably a DICTIONARY!.");
}
It's very strange, sometimes NSLog tells me "Its probably a DICTIONARY!" and the value is empty and the app does not work. And sometimes NSLog tells me "Its an ARRAY!" and the application works correctly.
But the data returned by the SCRIPT are always the same!
Thank you very much everyone for your help.
I use the following code to create a dictionary based on a JSON string received from the server. (I have downloaded JSONKit and embedded it into the project). The code below returns a legal JSON string from the server (parsed well on Android) but crashes when I try to convert it to a dictionary.
- (IBAction)submit
{
bool useSSL = true;
char *c_url="http://(rest of URL)";
NSString* url = [NSString stringWithFormat:#"%s" , c_url];
url = [NSString stringWithFormat:#"%#%#%s", url, self.label.text, "/keys"];
NSString * response = [self getDataFrom:url];
NSDictionary *dict = [response objectFromJSONString]; //generates SIGABRT!!
NSLog(#"%#",dict);
NSString *success = [dict valueForKey:#"success"];
}
- (NSString *) getDataFrom:(NSString *)url{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:#"GET"];
[request setURL:[NSURL URLWithString:url]];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *responseCode = nil;
NSData *oResponseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];
if([responseCode statusCode] != 200){
NSLog(#"Error getting %#, HTTP status code %i", url, [responseCode statusCode]);
return nil;
}
return [[NSString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding];
}
THANKS,
Simon
Found an answer here.
Answer says: "Figured it out... I had JSONKIt.h included in the project but for some weird reason, JSONKit.m was not included in the 'Compile Sources' under 'Build Phases' - once I added it manually it started working fine."
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"];
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];