I am parsing json and the url is returning an integer value. (e.g. 278)
-(void) connectionDidFinishLoading: (NSURLConnection *) connection{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSString *responseString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"JSON Response = %#",responseString);}
when I am printing response in NSLog, it gives out something like this
2012-09-15 18:02:02.091 Web Service[5190:f803] JSON Response = "278"
I don't want the output in quotes. I want it like
2012-09-15 18:02:02.091 Web Service[5190:f803] JSON Response = 278
how can i achieve this?
JSON
NSString *urlString = [NSString stringWithFormat:#"http://10.5.6.105/ARAPPWS/Service1/InsertEmp/name=%#,phone=%#",name.text,number.text];
NSURL *addUrl = [NSURL URLWithString:urlString];
NSURLRequest *addRequest = [NSURLRequest requestWithURL:addUrl];
(void)[NSURLConnection connectionWithRequest:addRequest delegate:self];
-(void) connection: (NSURLConnection *) connection didReceiveResponse:(NSURLResponse *)response
{
jsonData = [[NSMutableData alloc]init];
}
-(void) connection: (NSURLConnection *) connection didReceiveData:(NSData *)data
{
[jsonData appendData:data];
}
-(void) connectionDidFinishLoading: (NSURLConnection *) connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
responseString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
[self performSelector:#selector(uploadEmpImg:) withObject:nil afterDelay:1];
}
Thanks in advance.
You can use - [NSString integerValue] to obtain the actual numerical representation of the string:
NSLog(#"JSON response = %d", [responseString integerValue]);
Edit: the problem is that it returns a JSON fragment - strictly speaking it's not valid JSON. You can then use
[responseString substringWithRange:NSMakeRange(1, responseString.length - 2)]
to get the actual string value without the quotes and
[[responseString substringWithRange:NSMakeRange(1, responseString.length - 2)] intValue]
to get it as an integer.
Related
I need to display particular object for key(currency) using post method after getting response from web.
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController{
NSMutableData *mutableData;
NSMutableString *arr;
#define URL #"website"
// change this URL
#define NO_CONNECTION #"No Connection"
#define NO_VALUES #"Please enter parameter values"
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(IBAction)sendDataUsingPost:(id)sender{
[self sendDataToServer :#"POST"];
}
-(IBAction)sendDataUsingGet:(id)sender{
[self sendDataToServer : #"GET"];
}
-(void) sendDataToServer : (NSString *) method{
NSString *Branchid=#"3";
serverResponse.text = #"Getting response from server...";
NSURL *url = nil;
NSMutableURLRequest *request = nil;
if([method isEqualToString:#"GET"]){
NSString *getURL = [NSString stringWithFormat:#"%#?branch_id=%#", URL, Branchid];
url = [NSURL URLWithString: getURL];
request = [NSMutableURLRequest requestWithURL:url];
NSLog(#"%#",getURL);
}else{ // POST
NSString *parameter = [NSString stringWithFormat:#"branch_id=%#",Branchid];
NSData *parameterData = [parameter dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
url = [NSURL URLWithString: URL];
NSLog(#"%#", parameterData);
request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPBody:parameterData];
arr= [NSMutableString stringWithUTF8String:[parameterData bytes]];
NSLog(#"responseData: %#", arr);
//NSLog(#"%#",[[arr valueForKey:#"BranchByList"]objectForKey:#"currency"]);
}
[request setHTTPMethod:method];
[request addValue: #"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
//NSLog(#"%#",[connection valueForKeyPath:#"BranchByList.currency"]);
if( connection )
{
mutableData = [NSMutableData new];
//NSLog(#"%#",[connection valueForKeyPath:#"BranchByList.currency"]);
}
}
-(void) connection:(NSURLConnection *) connection didReceiveResponse:(NSURLResponse *)response
{
[mutableData setLength:0];
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[mutableData appendData:data];
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
serverResponse.text = NO_CONNECTION;
return;
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSMutableString *responseStringWithEncoded = [[NSMutableString alloc] initWithData: mutableData encoding:NSUTF8StringEncoding];
//NSLog(#"Response from Server : %#", responseStringWithEncoded);
NSLog(#"%#",responseStringWithEncoded );
NSLog(#"%#",[responseStringWithEncoded valueForKeyPath:#"BranchByList.currency"] );
NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[responseStringWithEncoded dataUsingEncoding:NSUnicodeStringEncoding] options:#{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
serverResponse.attributedText = attrStr;
// NSLog(#"%#",attrStr);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
i got response branch_id=3 but i want to show to "currency" but i tried lot but failure.
my response like this I need to display only currency.....
Response from Server :
{"BranchByList":
[
{"id":"342","flag_image":"http:\/\/demo.techzarinfo.com\/newantara\/images\/flags\/USD.png","units":"1","code":"USD B","currency":"US DOLLAR BIG","buy":"4.36","sell":"4.395","updated":"2016-04-11 03:24:24"
},
{"id":"342","flag_image":"http:\/\/demo.techzarinfo.com\/newantara\/images\/flags\/USD.png","units":"1","code":"USD B","currency":"US DOLLAR BIG","buy":"4.36","sell":"4.395","updated":"2016-04-11 03:24:24"
}
]};
Your response structure is:
-Dictionary
--Array
---Dictionary Objects
You need to convert your Data into NSDictionary to parse it.
Following code will do that for you:
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData: mutableData
options:kNilOptions
error:&error]; //Now we got top level dictionary
NSArray* responseArray = [json objectForKey:#"BranchByList"]; //Now we got mid level response array
//Get Embeded objects from response Array:
NSDictionary *priceDic = [responseArray objectAtIndex:0]; //Getting first object since you arent telling what the second object is for
NSString *buyingPrice = [priceDic objectForKey: #"buy"]; //Buying price
NSString *sellingPrice = [priceDic objectForKey:#"sell"]; //Selling price
NSString *currency = [priceDic objectForKey:#"currency"]; //Currency
Though this is only sticking to the point and getting the job done.
Proper way to get the job done would be to create a model class for response. Create a class inherited from NSObject and use it as model for this response. Add a initWithDic: method to that class, Pass it your response dic as parameter and delegate all this dictionary parsing to that method.
Also, NSURLConnection is deprecated since iOS 9.0. You should use NSURLSession instead.
Try This May be it will help you:-
NSString *str=[[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"str : %#",str);
NSDictionary *dict6 = [self cleanJsonToObject:responseData];
NSLog(#"str : %#",dict6);
NSMArray *array1 = [dict6 objectForKey:#"BranchByList"];
NSLog(#"DICT : %#",array1);
NSDictionary *Dict3 = [array1 objectAtIndex:0];
NSString *Str1 = [dict3 objectForKey:#"currency"];
NSLog(#"Str1 : %#",Str1);
- (id)cleanJsonToObject:(id)data
{
NSError* error;
if (data == (id)[NSNull null])
{
return [[NSObject alloc] init];
}
id jsonObject;
if ([data isKindOfClass:[NSData class]])
{
jsonObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
} else
{
jsonObject = data;
}
if ([jsonObject isKindOfClass:[NSArray class]])
{
NSMutableArray *array = [jsonObject mutableCopy];
for (int i = (int)array.count-1; i >= 0; i--)
{
id a = array[i];
if (a == (id)[NSNull null])
{
[array removeObjectAtIndex:i];
} else
{
array[i] = [self cleanJsonToObject:a];
}
}
return array;
} else if ([jsonObject isKindOfClass:[NSDictionary class]])
{
NSMutableDictionary *dictionary = [jsonObject mutableCopy];
for(NSString *key in [dictionary allKeys])
{
id d = dictionary[key];
if (d == (id)[NSNull null])
{
dictionary[key] = #"";
} else
{
dictionary[key] = [self cleanJsonToObject:d];
}
}
return dictionary;
} else
{
return jsonObject;
}
}
I have set up a simple Objective-C class in my iOS app which has one simple task, to download a JSON file, parse it and then pass back a NSString which contains a variable parsed from the downloaded JSON file.
The problem I have is that I am calling this class from another class and this all works great however I need to pass back the NSString to the class from which I am calling it from.
The problem is that the method passes back the empty NSString BEFORE connectionDidFinishLoading happens.... And so the NSString never gets assigned a string......
I have setup a while loop in my method but it doesn't really work.....
here is my code:
-(NSString *)get_user_icon:(NSString *)YT_ID {
// Set BOOL to 0 for initial setup.
icon_check = 0;
NSString *url_YT = [NSString stringWithFormat:YOUT_profile_part_2, YT_ID];
dispatch_queue_t downloadQueue = dispatch_queue_create("Icon downloader YouTube", NULL);
dispatch_async(downloadQueue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
NSURLRequest *theRequest_YT = [NSURLRequest requestWithURL:[NSURL URLWithString:url_YT]];
NSURLConnection *theConnection_YT = [[NSURLConnection alloc] initWithRequest:theRequest_YT delegate:self];
if (theConnection_YT) {
YT_JSON_FEED = [[NSMutableData alloc] init];
NSLog(#"Respoce happening...");
}
else {
NSLog(#"failed");
}
});
});
while (icon_check == 0) {
NSLog(#"Wait");
}
return icon_url;
}
/// Data loading ///
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[YT_JSON_FEED setLength:0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[YT_JSON_FEED appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSString *msg = [NSString stringWithFormat:#"Failed: %#", [error description]];
NSLog(#"%#",msg);
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSError *myError = nil;
NSDictionary *feed = [NSJSONSerialization JSONObjectWithData:YT_JSON_FEED options:NSJSONReadingMutableLeaves error:&myError];
icon_url = [[[[[feed objectForKey:#"items"] valueForKey:#"snippet"] valueForKey:#"thumbnails"] valueForKey:#"default"] valueForKey:#"url"];
icon_check = 1;
}
For a synchronous request (blocking until there is something to return), use NSURLConnection's sendSynchronousRequest:returningResponse:error: instead. Like so:
-(NSString *)get_user_icon:(NSString *)YT_ID {
NSString *url_YT = [NSString stringWithFormat:YOUT_profile_part_2, YT_ID];
NSURLRequest *theRequest_YT = [NSURLRequest requestWithURL:[NSURL URLWithString:url_YT]];
NSURLResponse* response = nil;
NSError* error = nil;
NSData* data = [NSURLConnection sendSynchronousRequest:theRequest_YT returningResponse:&response error:&error];
//Check response and error for possible errors here.
//If no errors.
NSDictionary *feed = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&myError];
icon_url = [[[[[feed objectForKey:#"items"] valueForKey:#"snippet"] valueForKey:#"thumbnails"] valueForKey:#"default"] valueForKey:#"url"];
return icon_url;
}
However this is not recommended. You need to change your API to be asynchronous. Either delegate-based, but more preferably, using block-based API.
I am parsing a string that I obtain from a website but get different results depending on how I download.
This way it works:
NSString *tagiString = #"http://tagesanzeiger.ch";
NSURL *tagiURL = [NSURL URLWithString:tagiString];
NSError *error;
NSString *text =[NSString stringWithContentsOfURL:tagiURL
encoding:NSASCIIStringEncoding
error:&error];
Te following way it does not work. I first download the data, feed it into the NSMutableData *articleData and then convert to a NSString with initWithData:encoding:
- (void)downloadWebsite
{
NSString *tagiString = #"http://tagesanzeiger.ch";
NSURL *websiteURL = [NSURL URLWithString:tagiString];
NSURLRequest *request = [NSURLRequest requestWithURL:websiteURL];
connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self
startImmediately:YES];
}
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
[articleData appendData:data];
}
- (NSString *)data
{
NSString *text = [[NSString alloc] initWithData:articleData
encoding:NSSymbolStringEncoding];
return text;
}
Seems like the resulting NSString *text content is not the same for both versions? Do I need to use a different string encoding? I have tried many without success.
Implement the delegate method connectionDidFinishLoading to ensure the connection loading has finished where you can call your data method. Also try to use NSASCIIStringEncoding instead of
NSSymbolStringEncoding.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *text = [[NSString alloc] initWithData:self.articleData
encoding:NSASCIIStringEncoding];
//do whatever you need to do with the text
}
Yes, you need to use a different string encoding. You can try NSUTF8StringEncoding. Here it's working for me. And utf-8 is almost the most popular encoding way.
Please do the following to reproduce the problem
NSString *url = #"http://qdreams.com/laura/index.php?request=EventWeekListings&year=2012&month=10&day=22";
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
NSString *json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%#" , json);
NSDictionary *deserializedData = [json objectFromJSONString];
deserializedData would contain nil. Expected behavior is to return proper dictionary.
Is that because total number of JSON dictionary elements exceed a certain threshold?
I would appreciate any help in this matter.
Why not just use the NSJSONSerialization method JSONObjectWithData:options:error: it worked fine for me.
NSString *url = #"http://qdreams.com/laura/index.php?request=EventWeekListings&year=2012&month=10&day=22";
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
NSArray *arr = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(#"%#",arr);
After Edit: I ran the code again this morning, and like you I got null. The problem with dataWithContentsOfURL. is that you have no control and no way to know what happened if something went wrong. So, I retested with the code below:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[self loadData];
}
-(void) loadData {
NSLog(#"loadData...");
self.receivedData = [[NSMutableData alloc] init];
NSURL *url = [NSURL URLWithString:#"http://qdreams.com/laura/index.php?request=EventWeekListings&year=2012&month=10&day=22"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: url cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval: 10.0];
[NSURLConnection connectionWithRequest:request delegate:self];
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSLog(#"didReceiveResponse...");
[self.receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(#"didReceiveData...");
NSLog(#"Succeeded! Received %ld bytes of data",[data length]);
[self.receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"didFailWithError...");
NSLog(#"Connection failed! Error - %# %#",[error localizedDescription],[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
//lblError.text = [NSString stringWithFormat:#"Connection failed! Error - %#",[error localizedDescription]];
self.receivedData = nil;
}
-(void) connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(#"connectionDidFinishLoading...");
NSError *error = nil;
id result = [NSJSONSerialization JSONObjectWithData:self.receivedData options:kNilOptions error:&error];
if (error) {
NSLog(#"%#",error.localizedDescription);
NSLog(#"%#",[[NSString alloc] initWithData:self.receivedData encoding:NSUTF8StringEncoding]);
}else{
NSLog(#"Finished...Download/Parsing successful");
if ([result isKindOfClass:[NSArray class]])
NSLog(#"%#",result);
}
}
There was an error, and the log of error.localizesDescription was: "The data couldn’t be read because it has been corrupted". So, it appears that there is something wrong with what's coming back from the server which prevents the JSON parser from working correctly. I also printed out the string along with the error message. Maybe you can look at it carefully and try to figure out what's wrong with the data.
looking at your json you start with the array value (using square brackets) without a name. try reformatting you response with something like this:
{"results":[...the rest of your response..]}
Im using json to load a table in my app from a twitter web service,
it works fine when using the search function,
http://search.twitter.com/search.json?q=mobtuts&rpp=5
the type of json response for the first one is: tenga: {"completed_in" = "0.076"; ...
but when I use the statuses function,
[NSURL URLWithString:#"http://twitter.com/statuses/user_timeline.json?id=hypercomputing"]];
the type of json response for the second one is: tenga: (
{
contributors = "<null>";
coordinates = "<null>";
"created_at" = "Thu Aug 04 23:26:05 +0000 2011";...
the result from json is different, so my app doesnt see the second call as a dictionary once imported from json, it sees it as a string, [because of the "(" ??]
here the code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
responseData = [[NSMutableData data] retain];
tweets = [NSMutableArray array];
NSURLRequest *request = [NSURLRequest requestWithURL:
// [NSURL URLWithString:#"http://twitter.com/statuses/user_timeline.json?id=hypercomputing"]];
[NSURL URLWithString:#"http://search.twitter.com/search.json?q=mobtuts&rpp=5"]];// hypercomputing
//[NSURL URLWithString:#"http://twitter.com/statuses/public_timeline.json?id=hypercomputing"]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
return YES;
}
#pragma mark NSURLConnection delegate methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[responseData release];
NSLog(#"string: %#",responseString);
NSDictionary *results = [responseString JSONValue];
NSLog(#"tenga: %#",results);
//NSLog(#"tenga: %#",[results objectForKey:#"("] );
//NSArray * keys = [results allKeys]; //ensa
//NSLog(#"keys: %#",keys); //ensayo
NSArray *allTweets = [results objectForKey:#"results"];
//NSArray *allTweets = [results objectForKey:#"user"];
NSLog(#"user is: %#",allTweets);
//[viewController setTweets:allTweets];
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
so how can I make sure to receive a dictionary from the json call?,
thanks a lot!
Instead of expecting a dictionary every time, considering testing the class of the incoming JSON object and writing code that handles each case.
Or, more to your point, write an intermediary web service to massage the JSON into something your app can recognize.
Since you're working with defined APIs offered by Twitter, you'll have to read up on the documentation to know what to expect and adjust your implementation accordingly. This isn't a case where you can change the data to meet your needs, you have to change the handling of the data.