Proper JSON encoding for HTTP POST request in iOS - ios

Posted a query previously about JSON parsing not working properly. Did more looking into it with a packet sniffer and also with another client that works properly and found out it's a syntax thing, that I still can't seem to solve.
The code in the bottom makes the HTTP request to have the JSON in it as:
{"key":"value"}
And my server is actually looking for a JSON in the following syntax:
key=%22value%22
I tried to write some code that does this manually, but figured there must be something out of the box for iOS, and I don't want to have faults in the future.
I messed around with it for a while trying to find the right code for the job, but couldn't (you can see some code I tried commented out). Can anyone help me?
+ (NSString*)makePostCall:(NSString*)urlSuffix
keys:(NSArray*)keys
objects:(NSArray*)objects{
NSDictionary *params = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
// NSString *dataString = [self getDataStringFromDictionary:params];
// NSData *jsonData = [dataString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params
options:0
error:&error];
// id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
// NSLog(#"%#", jsonObject);
if (!jsonData) {
// should not happen
NSError *error;
NSLog(#"Got an error parsing the parameters: %#", error);
return nil;
} else {
// NSString *jsonRequest = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
// NSLog(#"%#", jsonRequest);
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#", urlPrefix, urlSuffix]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0];
// NSData *requestData = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
// [request setValue:#"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody: jsonData];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
// TODO: handle error somehow
NSString *returnString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return returnString;
}
}

Related

NSJSONSerialization get error "index 1 beyond bounds for empty array"

sometimes I get error "index 1 beyond bounds for empty array" at this line
NSData *aData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
This is my full code
+ (NSDictionary *)getJson: (NSString *)strURL parameters:(NSDictionary *)parameters{
NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:strURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:15.0];
NSDictionary *headers = #{ #"content-type": #"application/json",
#"cache-control": #"no-cache",
#"postman-token": #"374a4b6f-b660-78f2-78bf-e22cf0156d8d"};
[request setHTTPMethod:#"POST"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];
NSURLResponse *response;
NSError *error;
NSData *aData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];*
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:aData options: NSJSONReadingMutableContainers error:&error];
return json;
}
Sometimes I get error, Sometimes not. I don't understands ? please help me, thanks everyone.
Whenever you get an error like the above, try the following:
NSData *aData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:aData options: NSJSONReadingMutableContainers error:&error];
if (error)
{
//1. See what the error says
NSLog(error.localizedDescription);
//2. Convert the original data into a string
NSString *jsonString = [[NSString alloc] initWithData:aData encoding: NSUTF8StringEncoding];
//Now take this string and validate it as a JSON at a place like http://jsonlint.com/
}
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: url
cachePolicy: defaultCachePolicy
timeoutInterval: defaultTimeoutInSeconds];
plz change your cachePolicy with defaultCachePolicy and try :)

How can i post json string to server

This is json string that I have to post...
{
"data": {
"description": "",
"current_value": "",
"serialno": "",
"condition": "",
"category": "category",
"purchase_value": "",
"new_or_used": "",
"gift_or_purchase": "",
"image": ""
},
"subtype": "fd3102d8-bc19-424b-bca2-774a8fd7ea6f"
}
How to post as JSON?
Surely this Q us a duplicate, but here's full example code, as one long routine. Just copy and paste.
First set up the JSON...
-(void)sendTestJsonCommand
{
NSMutableDictionary *dict = #{
#"heights":#"4_5_7",
#"score":#"4",
#"title":#"Some Title",
#"textBody":#"Some Long Text",
#"happy":#"y"
}.mutableCopy;
NSError *serr;
NSData *jsonData = [NSJSONSerialization
dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&serr];
if (serr)
{
NSLog(#"Error generating json data for send dictionary...");
NSLog(#"Error (%#), error: %#", dict, serr);
return;
}
NSLog(#"Successfully generated JSON for send dictionary");
NSLog(#"now sending this dictionary...\n%#\n\n\n", dict);
Next, correctly asynchronously send the command and json to your server...
#define appService [NSURL \
URLWithString:#"http://www.corp.com/apps/function/user/pass/id/etc"]
// Create request object
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:appService];
// Set method, body & content-type
request.HTTPMethod = #"POST";
request.HTTPBody = jsonData;
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:
[NSString stringWithFormat:#"%lu",
(unsigned long)[jsonData length]] forHTTPHeaderField:#"Content-Length"];
// you would almost certainly use MBProgressHUD at this point
// to display some sort of spinner or similar action on the UX
Finally, (A) connect correctly using NSURLConnection, and (B) correctly interpret the information which comes back to you from your server.
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *r, NSData *data, NSError *error)
{
if (!data)
{
NSLog(#"No data returned from server, error ocurred: %#", error);
NSString *userErrorText = [NSString stringWithFormat:
#"Error communicating with server: %#", error.localizedDescription]
return;
}
NSLog(#"got the NSData fine. here it is...\n%#\n", data);
NSLog(#"next step, deserialising");
NSError *deserr;
NSDictionary *responseDict = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&deserr];
NSLog(#"so, here's the responseDict\n\n\n%#\n\n\n", responseDict);
// LOOK at that output on your console to learn how to parse it.
// to get individual values example blah = responseDict[#"fieldName"];
}];
}
Hope it saves someone some typing!
Use following shnchronous request, you can use asynchronous request as well,
NSError *error;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:<Your API URL>]];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:<Your Mutable NSDictionary> options:NSJSONReadingMutableContainers error:&error];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:jsonData];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
//NSLog(#"results string = %#",[[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding]);
NSDictionary *temp= [NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableContainers error:nil];// This will convert Data to Json format
As per my point of view you can Use NSURLSeession with Asyn request (Try to implement NSURLSession)
NSData *postData =[NSJSONSerialization dataWithJSONObject:Data options:0 error:&error];
if (!error)
{
NSString *urlpart = [NSString stringWithFormat:#“Your URL];
NSURL *requestUrl = [NSURL URLWithString:urlpart];
NSMutableURLRequest *URLRequest = [NSMutableURLRequest requestWithURL:requestUrl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
URLRequest.allowsCellularAccess=YES;
[URLRequest setHTTPMethod:#"POST"];
[URLRequest setValue:#"application/json; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[URLRequest setHTTPBody:postData];
WebServiceManager *webserviceManager = [[WebServiceManager alloc] init];// this is your comman class for webServices connections
[webserviceManager sendRequest:URLRequest withOwner:self successAction:#selector(delegateMethod:) failAction:#selector(Error:)];
}
Replace:
NSData *postData = [jsonString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
With:
NSError *error;
NSData *postdata = [NSJSONSerialization dataWithJSONObject:jsonString options:0 error:&error];
An object that may be converted to JSON must have the following properties:
The top level object is an NSArray or NSDictionary.
All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.
All dictionary keys are instances of NSString.
Numbers are not NaN or infinity.

How to reach members of json with iOS

I want to reach from ios to a .net .asmx web service, and I reach with the following code:
NSString *urlString = #"http://www.****.com/Mobile.asmx/HelloWorld";
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod: #"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSError *errorReturned = nil;
NSURLResponse *theResponse =[[NSURLResponse alloc]init];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&theResponse error:&errorReturned];
if (errorReturned)
{
//...handle the error
}
else
{
NSString *retVal = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%#", retVal);
//...do something with the returned value
}
It returns clean json {"hellom":"Hello World","hellom2":"HelloWorld2"} but I can't reach members and value one by one
How can I do that?
You can convert JSON data into an object by using the following code...
NSData *jsonData = ... the data you got from the server
NSDictionary *object = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
object will then be a NSDictionary like this...
#{
hellom : #"Hello World",
hellom2: #"HelloWorld2"
}
You can then get to the keys and values like any other dictionary.

NSJsonSerialization Post request Method

I have used SBJsonParser and ASIFormDataRequest for Posting and JSON Parsing, like
NSString *urlStr = #"http:facebookpage/second/index.php";
NSURL *log_Url = [NSURL URLWithString:urlStr];
request = [ASIFormDataRequest requestWithURL:log_Url];
[ASIHTTPRequest setSessionCookies:nil];
[request setPostValue:uName.text forKey:#"uname"];
[request setPostValue:passWord.text forKey:#"pwd"];
[request setPostValue:#"login" forKey:#"req"];
[request startSynchronous];
NSError *error = [request error];
if (!error) {
response = [request responseString];
}
NSLog(#"%#",response);
Then For Parsing:
parser = [[SBJsonParser alloc]init ];
json_dic_values = [parser objectWithString:response error:nil];
NSString *status = [json_dic_values objectForKey:#"status"];
Url_pathforPages = [json_dic_values objectForKey:#"url"];
NSString *sessionID = [json_dic_values objectForKey:#"session_id"];
Here I need to know how can i do this same in NSJsonSerialization.
Everything is working fine in above method....
There are really only a few methods in NSJSONSerialization. Take a look at the documentation.
json_dic_values = [NSJSONSerialization JSONObjectWithData: [response dataUsingEncoding: NSUTF8StringEncoding] options: 0 error: &error];

Send JSON post data from iPhone Application Expressjs/Nodejs backend

This is my code for sending a post request to a nodejs backend.
CLLocation* location = [locationManager location];
CLLocationCoordinate2D coord = [location coordinate];
NSMutableURLRequest *request =
[NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://50.63.172.74:8080/points"]];
//[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPMethod:#"POST"];
NSDictionary* jsonDict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:coord.latitude], #"lat", [NSNumber numberWithFloat:coord.longitude], #"lng", nil];//dictionaryWithObjectsAndKeys:coord.latitude, nil]
NSString *postString;
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict
options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
error:&error];
if (! jsonData) {
NSLog(#"Got an error: %#", error);
} else {
postString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
(void)[[NSURLConnection alloc] initWithRequest:request delegate:self];
Using express I'm getting the request.body back on the server but it looks like this:
{ '{\n "lat" : 0.0,\n "lng" : 0.0\n}': '' }
and I can't access it by just saying request.body.lat since it comes back as undefined.
I want the body to look like:
{ "lat":0.0, "lng":0.0}
Any idea on how to do that using express?
May this help you.
Please replace 0.0 with your actual coordiantes
NSArray *keys = [NSArray arrayWithObjects:#"lat", #"lng", nil];
NSArray *objects = [NSArray arrayWithObjects:#"0.0",#"0.0", nil];
NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
NSData *jsonData ;
NSString *jsonString;
if([NSJSONSerialization isValidJSONObject:jsonDictionary])
{
jsonData = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:0 error:nil];
jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
}
NSString *requestString = [NSString stringWithFormat:
#"http://50.63.172.74:8080/points"];
NSURL *url = [NSURL URLWithString:requestString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setHTTPBody: jsonData];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:[NSString stringWithFormat:#"%d", [jsonData length]] forHTTPHeaderField:#"Content-Length"];
NSError *errorReturned = nil;
NSURLResponse *theResponse =[[NSURLResponse alloc]init];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&theResponse error:&errorReturned];
if (errorReturned) {
NSLog(#"Error %#",errorReturned.description);
}
else
{
NSError *jsonParsingError = nil;
NSMutableArray *arrDoctorInfo = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers|NSJSONReadingAllowFragments error:&jsonParsingError];
NSLog(#"Dict %#",arrDoctorInfo);
}
The problem is that after you use NSJSONSerialization to obtain a NSData object containing your JSON data, you then create postString from that data. Eliminate that unnecessary step, and just do:
[request setHTTPBody:jsonData];
And you should get the expected JSON in your server-side code.

Resources