-JSONValue failed. Error trace is: in Google currency converter in iPhone - iphone

I need live currency rates. I am using a Google API available in the URL
http:://www.google.com/ig/calculator?hl=en&q=1USD=?INR
Whenever am hitting that URL using json parsing, then response data getting nil. I am not getting what is the exact error in that code
#define openexchangeURl #"http://www.google.com/ig/calculator?hl=en&q=1USD=?INR"
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:openexchangeURl]];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
values =[responseString JSONValue];

This will get you live rates:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://rate-exchange.appspot.com/currency?from=USD&to=INR&q=1"]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSDictionary *parsedDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
CGFloat value = [parsedDict[#"rate"] floatValue];
NSLog(#"Value: %f", value);
}];
The JSON response from that api looks like this:
{
to: "INR",
rate: 54.8245614,
from: "USD",
v: 54.8245614
}
Your original request didn't have an NSURLConnection and the response was not valid JSON (did not have double-quoted values for each item in the hash).

Related

JSON serialisation in AFNewtorking is failing

I am trying to perform GET requests that returns JSON string from a web-service using AFNetworking but I am receiving the following error from AFNetworking 1.3.3
#"JSON text did not start with array or object and option to allow fragments not set."
and here is my JSON which is a valid JSON string , I used many online validators to make sure
"{\"ErrorCode\":0,\"VerCode\":\"8595\"}"
AFNetworking Code that is not working
NSString *urlString = [BASE_URL stringByAppendingString:paramseters];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:BASE_URL]];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"GET"
path:urlString
parameters:nil];
AFJSONRequestOperation *operation =
[AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSDictionary *jsonDic = (NSDictionary *)JSON;
success(jsonDic);
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
CPError *cpError = [CPError CPErrorWithErrorCode:error.code errorDesc:error.localizedDescription];
failure(cpError);
}];
[operation start];
I was able to parse the JSON into NSDictionary using the below code but I want to be able to use AFNetworking in order to make use of it's built in features , is there a way to make AFNetworking understands my JSON string ?
NSURL *url = [NSURL URLWithString:#"http://103.1.173.60/ims-mobile-wcf/MobileWCF.svc/AddUpdateMobileClient/123123/443da4444/1/1"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:120];
[request setHTTPMethod:#"GET"];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSLog(#"%#",connectionError);
NSError *error = nil;
NSString *JSONString = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSDictionary *JSONDictionary =
[NSJSONSerialization JSONObjectWithData: [JSONString dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &error];
}];
I'll take a stab and say the reason is that the response string appears to be in quotes, if this is the case then the error is very clear - the Fragments option is not set. Do a a global search for "JSONReadingOptions" and you'll find the place in AFNetworking where the response is serialized into a foundation object (in version 1.3 it's AFJsonRequestOperation line 79, it looks like your using 2.0) is basically exactly what you are doing manually. If you do as arturdev suggests and set the reading options to be NSJSONReadingAllowFragments it should work.
Try:
AFJSONRequestOperation *operation = ...
operation.JSONReadingOptions = NSJSONReadingAllowFragments;
[operation start];
This is wrong:
NSError *error = nil;
NSString *JSONString = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSDictionary *JSONDictionary =
[NSJSONSerialization JSONObjectWithData: [JSONString dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &error];
JSONObjectWithData: does not return an NSString, it returns an object: NSArray or NSDictionary, in your case a NSDictionary
Just use:
NSError *error = nil;
NSDictionary *resultDictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];

Display the rendered feed in a view which is in NSData

The below is the code I used to get a data of URL from a facebook page. I need to display those datas in a view. How to do it?
NSURL *URL = [NSURL URLWithString:#"https://www.facebook.com/104958162837/posts/10151442797857838"];
NSURLRequest* request = [NSURLRequest requestWithURL:URL];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data,
NSError * error) {
if (!error){
NSLog(#"%#",data);
// I want to render this data in a view.
}
}];
I can get the proper values in the in NSData. I want to display those datas in a webview or uilabel or something to display those datas.
See this code.
id dataObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
You can get json string to NSObject(like NSDictionary, NSArray)
You need to convert NSData into NSString and then use that NSString for display.
NSURL *URL = [NSURL URLWithString:#"https://www.facebook.com/xxxxxx/posts/xxxxxxxxxx"];
NSURLRequest* request = [NSURLRequest requestWithURL:URL];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data,
NSError * error) {
if (!error){
NSLog(#"%#",data);
// I want to render this data in a view.
NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//[lbl setText:myString];
/** EDIT : As you are getting HTML Response, you can display that in WebView like this **/
[webview loadHTMLString:myString baseURL:nil];
}
}];

AFJSONRequestOperation with JSON encoded as NSISOLatin1StringEncoding crashing

I want to use AFNetworking more specifically AFJSONRequestOperation in a project to allow for easy async calls. I quickly tried using the sample code from AFNetworking GitHub Page
NSURL *url = [NSURL URLWithString:#"https://alpha-api.app.net/stream/0/posts/stream/global"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(#"App.net Global Stream: %#", JSON);
}
failure:nil];
[operation start];
Which works fine, But when I use the URL for MetOffice Datapoint it crashes, I believe this might be because of the encoding type of the JSON feed being NSISOLatin1StringEncoding which causes a problem with NSJSONSerialization
The way I currently handle this is
NSString *string = [NSString stringWithContentsOfURL:kMetOfficeAllSites encoding:NSISOLatin1StringEncoding error:&error];
NSData *metOfficeData = [string dataUsingEncoding:NSUTF8StringEncoding];
id jsonObject = [NSJSONSerialization JSONObjectWithData:metOfficeData options:kNilOptions error:&error]
But how do I handle this situation with AFJSONRequestOperation?
Thanks in Advance

AFNetworking POST to REST webservice

Brief backstory, our previous developer used ASIHTTPRequest to make POST requests and retrieve data from our webservice. For reasons unknown this portion of our app stopped working. Seemed like good enough time to future proof and go with AFNetworking. REST webservice runs on the CakePHP framework.
In short I am not receiving the request response string using AFNetworking.
I know the webservice works because I am able to successfully post data and receive the proper response using curl:
curl -d "data[Model][field0]=field0value&data[Model][field1]=field1value" https://example.com/api/class/function.plist
Per the previous developer's instructions I came up with the following.
#import "AFHTTPRequestOperation.h"
…
- (IBAction)loginButtonPressed {
NSURL *url = [NSURL URLWithString:#"https://example.com/api/class/function.plist"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:[usernameTextField text] forHTTPHeaderField:#"data[User][email]"];
[request setValue:[passwordTextField text] forHTTPHeaderField:#"data[User][password]"];
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"operation hasAcceptableStatusCode: %d", [operation.response statusCode]);
NSLog(#"response string: %# ", operation.responseString);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", operation.responseString);
}];
[operation start];
}
output:
operation hasAcceptableStatusCode: 200
response string: a blank plist file
attempted solution 1:
AFNetworking Post Request
the proposed solution uses a function of AFHTTPRequestOperation called operationWithRequest. However, when I attempt to use said solution I get a warning "Class method '+operationWithRequest:completion:' not found (return type defaults to 'id'"
attempted solution 2: NSURLConnection. output: I'm able to print the success log messaged but not the response string.
*update - returns blank plist.
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSString *httpBodyData = #"data[User][email]=username#example.com&data[User][password]=awesomepassword";
[httpBodyData dataUsingEncoding:NSUTF8StringEncoding];
[req setHTTPMethod:#"POST"];
[req setHTTPBody:[NSData dataWithContentsOfFile:httpBodyData]];
NSHTTPURLResponse __autoreleasing *response;
NSError __autoreleasing *error;
[NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
// *update - returns blank plist
NSData *responseData = [NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil];
NSString *str = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"responseData %#",str);
if (error == nil && response.statusCode == 200) {
// Process response
NSLog(#"success");//returns success code of 200 but blank
NSLog(#"resp %#", response );
} else {
// Process error
NSLog(#"error");
}
These are the essential (stripping out conditions I've made for my own use) lines that ended up satisfying my request to the web service. Thanks for the suggestions #8vius and #mattt !
- (IBAction)loginButtonPressed {
NSURL *baseURL = [NSURL URLWithString:#"https://www.example.com/api/class"];
//build normal NSMutableURLRequest objects
//make sure to setHTTPMethod to "POST".
//from https://github.com/AFNetworking/AFNetworking
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
[httpClient defaultValueForHeader:#"Accept"];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
[usernameTextField text], kUsernameField,
[passwordTextField text], kPasswordField,
nil];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST"
path:#"https://www.example.com/api/class/function" parameters:params];
//Add your request object to an AFHTTPRequestOperation
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc]
initWithRequest:request] autorelease];
//"Why don't I get JSON / XML / Property List in my HTTP client callbacks?"
//see: https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ
//mattt's suggestion http://stackoverflow.com/a/9931815/1004227 -
//-still didn't prevent me from receiving plist data
//[httpClient registerHTTPOperationClass:
// [AFPropertyListParameterEncoding class]];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:
^(AFHTTPRequestOperation *operation,
id responseObject) {
NSString *response = [operation responseString];
NSLog(#"response: [%#]",response);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", [operation error]);
}];
//call start on your request operation
[operation start];
[httpClient release];
}
Use AFHTTPClient -postPath:parameters:success:failure:, passing your parameters (nested dictionaries/arrays are fine). If you're expecting a plist back, be sure to have the client register AFPropertyListRequestOperation.
In any case, setValue:forHTTPHeaderField: is not what you want here. HTTP headers are for specifying information about the request itself; data is part of the request body. AFHTTPClient automatically converts parameters into either a query string for GET requests or an HTTP body for POST, et al.

Get driving direction in iPhone

I read both iPhone and Google Map for iPhone EULA and want to implement a static driving direction map in my iPhone application (native).
I am finding a simple way to get route data and display with build-in route display feature in iOS 4 SDK' Mapkit.
Is there any programmer implement a feature like this with Google Map and Bing Map? Since Bing Map provided routing data in SOAP web service, it's seem easier to programming driving direction with Bing's service.
I found the solution for this. Just use a JSON parser to got google map API
For example:
NSDictionary *testJsondata = [self testJson:GoogleMapXMLDirectionQueryString];
NSLog(#"Here is the title of the response: %#", [testJsondata valueForKey:#"status"]);
for (id key in testJsondata) {
NSLog(#"key: %#, value: %#", key, [testJsondata objectForKey:key]);
}
}
- (NSDictionary *) testJson : (NSString*) url
{
id response = [self objectWithUrl:[NSURL URLWithString:url]];
NSDictionary *feed = (NSDictionary *)response;
return feed;
}
- (id) objectWithUrl:(NSURL *)url
{
SBJsonParser *jsonParser = [SBJsonParser new];
NSString *jsonString = [self stringWithUrl:url];
// Parse the JSON into an Object
return [jsonParser objectWithString:jsonString error:NULL];
}
- (NSString *)stringWithUrl:(NSURL *)url
{
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:30];
// Fetch the JSON response
NSData *urlData;
NSURLResponse *response;
NSError *error;
// Make synchronous request
urlData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse: &response
error: &error];
// Construct a String around the Data from the response
return [[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding];
}
- (NSString *)getDirectionInXML:(NSString *)GoogleMapXMLDirectionQueryString
{
NSError *error;
NSURLResponse *response;
NSData *dataReply;
NSString *stringReply;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:
[NSURL URLWithString: [NSString stringWithFormat:GoogleMapXMLDirectionQueryString]]];
[request setHTTPMethod: #"GET"];
dataReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
stringReply = [[NSString alloc] initWithData:dataReply encoding:NSUTF8StringEncoding];
return stringReply;
}