JSON to NSDictionary from http post request - objective-c

I created a simple php file to output a JSON String:
<?
$test = $_POST["hashcode"];
if ($ttest != "")
{
$arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'couponcode' => $test);
echo json_encode($arr);
}
?>
I am trying to use objective-C language to retrieve this json and parse it into a NSDictionary. I am currently using the JSON framework, but it isn't working for me.
NSHTTPURLResponse * response;
NSError * error;
NSString *post = #"hashcode=asdf1234fdsa";
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:#"www.ski-inndronten.nl/json.php"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSData *testJSON = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *jsonString = [testJSON JSONRepresentation];
NSLog(#"String = %#",jsonString);
NSDictionary *testDict = [jsonString JSONValue];
NSLog(#"testDict = %#",testDict);
I hope you can help me out since I have no idea what I did wrong. (I am outputting NULL objects)

OK there are two errors:
the first, you forgot to add "http://" in front of your URL string. If you don't do it the request will fail and returned data is nil.
the second, you are sending the incorrect application/json content type, if you do this the php will return an invalid answer. Simply remove this setting and the returned code will be correct.
By the way you can facilitate your debugging by logging the returned data as below:
NSData *testJSON = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"%#",[[NSString alloc] initWithData:testJSON encoding:NSUTF8StringEncoding]);
If you do these two corrections, the answer will be correctly returned.

Related

POST form data in Objective C

I have to pass form data in body part. here is postman screen short for better understanding.
body part
content type
here is my code what I had try.
NSString *Accesstoken = [NSString stringWithFormat:#"Bearer %#",tokenInfo.access_token];
// parameter is String object : "user_id=18&deal_id=218"
//NSDictionary *tmp = [[NSDictionary alloc] initWithObjectsAndKeys:
#"user_id", #"18487",
#"deal_id", #"218",
nil];
// NSError *errorr;
// NSData *postdata = [NSJSONSerialization dataWithJSONObject:tmp options:0 error:&errorr];
[request setValue:Accesstoken forHTTPHeaderField:#"Authorization"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
// NSData *postData = [parameter dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[postData length]];
// [request setHTTPBody:postData];;
// [request setHTTPBody:[parameter dataUsingEncoding:NSUTF8StringEncoding]];
// [request setHTTPBody:[NSJSONSerialization dataWithJSONObject:#{#"user_id":#"18487",#"deal_id":#"218" } options:0 error:nil]];
for above code I am getting http status code : 404 its wrong. and when I try in postman I am getting 401 its perfect I want that. Please help Thanks.
Just export the request from POSTMAN in objective-C : https://www.getpostman.com/docs/postman/sending_api_requests/generate_code_snippets

iPhone POST request with JSON data

I am building my first iPhone application and have run into problems trying to POST json data to my MongoDB database.
This is my code thus far:
NSString *post = [NSString stringWithFormat:#"{\"name\":\"blah\"&\"reputation\":\"100\"&\"phone_number\":\"1234\"}"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http://myURL/users"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
//[request setValue:#"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPBody:postData];
NSURLResponse *response;
NSData *POSTReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSString *theReply = [[NSString alloc] initWithBytes:[POSTReply bytes] length:[POSTReply length] encoding: NSASCIIStringEncoding];
NSLog(#"Reply: %#", theReply);
I get this response in the console:
2014-06-10 16:07:09.758 SocialEyez[2226:70b] Reply: {
"_id": "5397656dd7ec395c1b808230"
}
So even though the POST seems to go through fine, there is something wrong with my formatting which prevents the JSON data from being entered.
I've tried to format the NSString a hundred different ways but nothing seems to work.
Please help me out!!
EDIT:
When I send this request over jQuery:
jQuery.post("http://site/users", { "name": "George Washington", "reputation": "pres", "phone_number": "1234" }, function (data, textStatus, jqXHR) { console.log("Post resposne:"); console.dir(data); console.log(textStatus); console.dir(jqXHR); });
I get the following response:
_id: "53978f4cd7ec395c1b808247"
name: "George Washington"
reputation: "pres"
phone_number: "1234"
This example assumes that the post data should be JSON.
Create the JSON from a dictionary, let NSJSONSerialization add the JSON syntax.
// #"{\"name\":\"blah\"&\"reputation\":\"100\"&\"phone_number\":\"1234\"}"
// Create the dictionary
NSDictionary *postDict = #{#"name":#"blah", #"reputation":#"100", #"phone_number":#"1234"};
// Create the JSON data
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:postDict options:0 error:&error];
// Just for this example: display the jsonData as an ASCII string
NSLog(#"jsonData as String: %#", [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]);
NSLog output:
jsonData: <7b226e61 6d65223a 22626c61 68222c22 72657075 74617469 6f6e223a 22313030 222c2270 686f6e65 5f6e756d 62657222 3a223132 3334227d>
jsonData as String: {"name":"blah","reputation":"100","phone_number":"1234"}

Objective C NSMutableURLRequest GET request returns null JSON

trying get Data from server using #"GET" request,
this following code returns null all time:
is anybody finding an issue with my following code?
or it's can be server side Issue..
?
thank for your help!
+ (id)sendParam:(NSString*)ParamString url:(NSString*)url{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
NSString *post = ParamString;
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d",[postData length]];
[request setURL:[NSURL URLWithString:url]];
NSLog(#"postLength =%#",postLength);
[request setHTTPBody:postData];
[request setHTTPMethod:#"GET"];
[request addValue:ParamString forHTTPHeaderField:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSURLResponse *response;
NSError *error;
NSData *aData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSMutableArray*jsonReturn = [[NSMutableArray alloc]init];
jsonReturn = (NSMutableArray*)[NSJSONSerialization JSONObjectWithData:aData options:kNilOptions error:&error];
NSLog(#"jsonReturn %#",jsonReturn);
return jsonReturn;
}
after Editing:
+ (id)sendParam:(NSString*)ParamString url:(NSString*)url{
NSString*StringGETMETHOD = [NSString stringWithFormat:#"%#%#",url,ParamString];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:[NSURL URLWithString:StringGETMETHOD]];
[request setHTTPMethod:#"POST"];
NSURLResponse *response;
NSError *error;
NSData *aData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"aData=%#",aData);
if (aData) {
jsonReturn=(NSMutableArray*)[NSJSONSerialization JSONObjectWithData:aData options:kNilOptions error:&error];
NSLog(#"jsonReturn %#",jsonReturn);
}
If you want to use GET for getting response from server just you can try in following method
//just give your URL instead of my URL
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://api.worldweatheronline.com/free/v1/search.ashx?query=London&num_of_results=3&format=json&key=xkq544hkar4m69qujdgujn7w"]];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"content-type"];
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
//You need to check response.Once you get the response copy that and paste in ONLINE JSON VIEWER.If you do this clearly you can get the correct results.
//After that it depends upon the json format whether it is DICTIONARY or ARRAY
NSDictionary *jsonArray = [NSJSONSerialization JSONObjectWithData:responseData options: NSJSONReadingMutableContainers error: &err];
NSArray *array=[[jsonArray objectForKey:#"search_api"]objectForKey:#"result"];
I very much doubt that you should send this parameter as a HEADER field.
I also would think that you should be sending a POST and not a GET.
Setting jsonReturn to [[NSMutableArray alloc] init] is nonsense. Explain to yourself why you are doing it instead of setting jsonReturn to nil
Logging the jsonReturn is nonsense, because all the interesting stuff has disappeared. You should log the response and the data that was returned, at least if jsonReturn = nil.
You seem to be confused between GET and POST. You are doing a GET, but supplying data like a POST (usually does, though it isn't mandated, or precluded to use the body data for a GET).
Generally, you don't want to use body data for a GET, it isn't usual / expected so any number of different issues could be occurring. Either change setHTTPMethod: to #"POST" so you are doing a POST properly, or change the parameters to be part of the request URL.
It really all depends what the server expects (and can handle). This is what you need to know and match against...
Subsequently you have a different issue. The param string you supply has characters in it that need to be encoded (like spaces). Use stringByAddingPercentEscapesUsingEncoding: on the param string before you send it to escape these characters.
It works in a browser because it is adding the escape characters for you (which you should see in the browser address bar after it has loaded the response).
i found my issue:
sending paramString Using "Get" Method, cannot send parameters with space between letters.. example: "tel aviv" should be "tel%20aviv"
by adding the following code line:
**urlParam = [urlParam
stringByReplacingOccurrencesOfString:#" " withString:#"%20"];**
fix code:
+ (id)sendParam:(NSString*)ParamString url:(NSString*)url{
NSString* urlParam = [NSString stringWithFormat:#"%#%#",url,ParamString];
urlParam = [urlParam
stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlParam]];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"content-type"];
NSURLResponse *response;
NSError *error;
NSData *aData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"aData=%#",aData);
if (aData) {
jsonReturn=(NSMutableArray*)[NSJSONSerialization JSONObjectWithData:aData options:kNilOptions error:&error];
NSLog(#"jsonReturn %#",jsonReturn);
}
thank you all !

NSURLConnection closes early on GET

I'm working on a method to centralize my URL connections for sending and receiving JSON data from a server. It works with POST, but not GET. I'm using a Google App Engine server and on my computer it'll handle the POST requests and return proper results (and log appropriately), but I get the following error when I try the request with a GET method:
Error Domain=kCFErrorDomainCFNetwork Code=303 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error 303.)" UserInfo=0xd57e400 {NSErrorFailingURLKey=http://localhost:8080/api/login, NSErrorFailingURLStringKey=http://localhost:8080/api/login}
In addition, the GAE dev server shows a "broken pipe" error, indicating that the client closed the connection before the server was finished sending all data.
Here's the method:
/* Connects to a given URL and sends JSON data via HTTP request and returns the result of the request as a dict */
- (id) sendRequestToModule:(NSString*) module ofType:(NSString*) type function:(NSString*) func params:(NSDictionary*) params {
NSString *str_params = [NSDictionary dictionaryWithObjectsAndKeys:func, #"function", params, #"params", nil];
NSString *str_url = [NSString stringWithFormat:#"%#%#", lds_url, module];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:str_url]];
NSData *data = [[NSString stringWithFormat:#"action=%#", [str_params JSONString]] dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPMethod:type];
[request setHTTPBody:data];
[request setValue:[NSString stringWithFormat:#"%d", [data length]] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSError *error = nil;
NSURLResponse *response = nil;
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"Error: %#", error);
NSLog(#"Result: %#", [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]);
return [result objectFromJSONData];
}
A sample call would be:
NSDictionary *response = [fetcher sendRequestToModule:#"login" ofType:#"GET" function:#"validate_email" params:dict];
Again, this works with a POST but not a GET. How can I fix this?
In my case i was not calling [request setHTTPMethod: #"POST" ]
I think the root cause is you have an invalid URL.
JSON encoding will include things like '{', '}', '[' and ']'. All of these need to be URL encoded before being added to a URL.
NSString *query = [NSString stringWithFormat:#"?action=%#", [str_params JSONString]];
query = [query stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#", str_url, query]];
To directly answer your question:
According to CFNetwork Error Codes Reference the error is kCFErrorHTTPParseFailure. This means the client failed to correctly parse the HTTP response.
The reason why is that a GET doesn't include a body. Why would you want to submit JSON in a GET anyways?
If the target api returns data only you pass it in the url params.
If you want to send data and "get" a response use a post and examine the body on return.
Sample Post:
NSError *error;
NSString *urlString = [[NSString alloc] initWithFormat:#"http://%#:%#/XXXX/MVC Controller Method/%#",self.ServerName, self.Port, sessionId ];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding ]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
// hydrate the remote object
NSString *returnString = [rdc JSONRepresentation];
NSData *s10 = [returnString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:s10];
NSURLResponse *theResponse = [[NSURLResponse alloc] init];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&theResponse error:&error];
NSString *message = [[NSString alloc] initWithFormat: #"nothing"];
if (error) {
message = [[NSString alloc] initWithFormat:#"Error: %#", error];
} else {
message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
NSLog(#"%#", message);
return message;

JSON for Objective-C returns error "Illegal start of token [r]"

I am attempting to connect to a web page and return a JSON string. This string simply needs to be parsed in JSON and returned into an NSArray that I have waiting for it. The problem is that JSON doesn't always return the results. Sometimes, it works well. Sometimes, it returns (null), citing the error below.
self.accounts = nil; // Clear the NSArray
NSString *post = [NSString stringWithFormat:#"username=%#", username.text];
NSData *postData = [NSData dataWithBytes: [post UTF8String] length: [post length]];
// Submit login data
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString: #"http://###.#####.###/app/getaccts.php"]];
[request setHTTPMethod: #"POST"];
[request setValue: #"application/x-www-form-urlencoded" forHTTPHeaderField: #"Content-Type"];
[request setHTTPBody: postData];
// Retreive server response
NSURLResponse *response;
NSError *err;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *content = [NSString stringWithUTF8String:[returnData bytes]];
accounts = [[content JSONValue] allValues]; // Parse JSON string into the array
NSLog(#"Array: %#", accounts);
The page I am submitting to returns this:
{"1":"856069060", "2":"856056407"}
JSON logs the following error:
-JSONValue failed. Error is: Illegal start of token [r]
Can I get a little more info ... specifically, I'd like you to check the return value of your sendSynchronousRequest so can you make this change and rerun your test:
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
if (returnData == nil) {
NSLog(#"ERROR: %#", err);
} else {
NSLog(#"DATA: %#", returnData);
}