I am using web service for my iOS app.
I know how to send http post request via URL (not http Body) and get response using NSURLConnection Delegate.
But now there is better approach which I am following for web service and passing parameters in request body. I looked for library on google and found this.
But the code is bit difficult for me and I suppose there should be function for the same, which can make this bit easier.
Is there any? the code so far is below.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
initWithURL:[NSURL
URLWithString:**WebService URL**]];
[request setHTTPMethod:#"POST"];
[request setValue:#"text/json" forHTTPHeaderField:#"Content-type"];
NSString *jsonString = [NSString stringWithFormat:#"{\n\"username\":\"%#\",\n\"%#\":\"%#\",\n\"%#\":\"%#\",\n\"%#\":%#,\n\"%#\":%#,\n\"version\":%#,\n\"name\":\"%#\"\n}",userName, #"password",pass,#"accessToken",token,#"isOnline",#"True",#"accountType",type,#"False",name];
[request setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
jsonString in this code is the http body. I want to pass parameters in request body.
Now, after executing this code i get null in NSData variable. whereas my web service function returns a value and also it returns if the execution was successful.
what is wrong in my code.
Thank you.
Thanks for your answers. Finally I found the exact solution which works absolutely fine.
I have used NSURLConnection delegate and I am passing parameter in HTTPBody in json. I am receiving response also in json.
But sending parameter directly as json is not permitted in httprequestbody so we need to take it in NSData and set content-type.
Note: specifying content type is very important.
-(void)sendDataToServer:(NSString*)userName :(NSString*)name{
{
NSArray *keys = [NSArray arrayWithObjects: #"name",#"accountType",#"isOnline",#"username", nil];
NSArray *objects = [NSArray arrayWithObjects:name,[NSNumber numberWithBool:false],[NSNumber numberWithBool:false],userName, nil];
NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
NSString *myJSONString =[jsonDictionary JSONRepresentation];
NSData *myJSONData =[myJSONString dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"myJSONString :%#", myJSONString);
NSLog(#"myJSONData :%#", myJSONData);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:Your URL string]];
[request setHTTPBody:myJSONData];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
if (theConnection) {
NSLog(#"connected");
receivedData=[[NSMutableData alloc]init];
} else {
NSLog(#"not connected");
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[receivedData appendData:data];
NSString* responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"response: %#",responseString);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do something with the data
// receivedData is declared as a method instance elsewhere
NSLog(#"Succeeded! Received %lu data",(unsigned long)[receivedData length]);
NSString* responseString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
NSLog(#"response: %#",responseString);
NSError *myError = nil;
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:receivedData options:NSJSONReadingMutableLeaves error:&myError];
// show all values
for(id key in res) {
id value = [res objectForKey:key];
NSString *keyAsString = (NSString *)key;
NSString *valueAsString = (NSString *)value;
NSLog(#"key: %#", keyAsString);
NSLog(#"value: %#", valueAsString);
}
}
P.S : You will need to add JSon files for serialization(json.h).
Check out this question nsurlrequest post body and this http post encode type
Generally, the body should conforms to "key=value" format
To your question, you need a "key" for your jsonString
[request setHTTPBody:[NSString stringWithFormat:#"postedJson=%#", jsonString]];
postedJson is the key through which you'll get the value of it at server side.
such as:
request["postedJson"]
the value returned would be the jsonString you construted
There is a typo in your sample code, this would explain the null result :
NSString ***jsonString** = [NSString stringWithFormat:#"{\n\"username\":\"%#\",\n\"%#\":\"%#\",\n\"%#\":\"%#\",\n\"%#\":%#,\n\"%#\":%#,\n\"version\":%#,\n\"name\":\"%#\"\n}",userName, #"password",pass,#"accessToken",token,#"isOnline",#"True",#"accountType",type,#"False",name];
[request setHTTPBody:[**xmlString** dataUsingEncoding:NSUTF8StringEncoding]];
Related
I have made a login form. Fields r email and password. Now i want to POST the data from fields to specific url how it can be done. I'm totally new to IOS. Can anybody help me?? How to do HTTP request and JSON parsing?
/*********See this**********/
-(void)webServiceCall{
NSString *dataToSend = [NSString stringWithFormat:#"Username=%#&Password=%#“,<userIdEnter Here>,<Password enter here>];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSString *Length = [NSString stringWithFormat:#"%d",[postData length]];
[request setURL:[NSURL URLWithString:#“WEBURL”]];
[request setHTTPMethod:#"POST"];
[request setValue:Length forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
// check connection if you want
/*****get response in delegates*******/
- (void)connection:(NSURLConnection *)connection didReceiveResponse:
(NSURLResponse *)response {
// A response has been received, this is where we initialize the instance var you created
// so that we can append data to it in the didReceiveData method
// Furthermore, this method is called each time there is a redirect so reinitializing it
// also serves to clear it
_responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data
{
/**************/
NSString* newStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
// NSArray* latestLoans = [json objectForKey:#"loans"];
NSLog(#"json: %#", json);
[_responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"Error --> %#",error.localizedDescription);
/***************/
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *responseString = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
NSError *error = nil;
id result = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
// use Result
self.responseData = nil;
}
I am trying to send multiple parameter for a registration usage. Here is my Code for Posting data :
-(void)PostRegistrationData:(NSString *)userEmail :(NSString *)Password{
NSDictionary *params = #{
#"username":#"something",
#"password":#"aFilter",
#"email":#"aCategory",
#"type":#"aCategory",
#"request_type":#"aCategory"
};
/* We iterate the dictionary now
and append each pair to an array
formatted like <KEY>=<VALUE> */
NSMutableArray *pairs = [[NSMutableArray alloc] initWithCapacity:0];
for (NSString *key in params) {
[pairs addObject:[NSString stringWithFormat:#"%#=%#", key, params[key]]];
}
/* We finally join the pairs of our array
using the '&' */
NSString *requestParams = [pairs componentsJoinedByString:#"&"];
NSData *postData = [requestParams dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://teknofolk.com/spisrett_admin/slave/signup.php?"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLConnection *theConnection = [NSURLConnection connectionWithRequest:request delegate:self];
if( theConnection ){
// indicator.hidden = NO;
NSMutableData *mutableData = [[NSMutableData alloc]init];
}
}
But no data i getting inserted . Am i missing something?
You have various choices what you want to use.
First option:
NSURLResponse *res = nil;
NSError *err = nil;
NSData *retData = [NSURLConnection sendSynchronousRequest:request returningResponse:&res error:&err];
(you have also the async way for this option).
or you can also follow your code and continue with this:
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
and the request will be async and will call this methods (you need that this view controller responds to the NSURLConnectionDelegate and NSURLConnectionDataDelegate):
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse
*)response
{
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}
It was my mistake in the parameter.
NSDictionary *params = #{
#"username":#"something",
#"password":#"aFilter",
#"email":#"aCategory",
#"type":#"aCategory",
#"request_type":#"aCategory"
};
Worked with simply this :
#"type":#"1",
#"request_type":#"2"
};
In my insertion i was passing wrong value on type and request type. Thanks to all for all
I have am NSURLConnection to get a JSON value from my web server. The code is placed in a class which can be called from other UIViewControllers.
I am a little unsure on how to return the JSON data from the class however.
Here is what I have tried:
+(NSJSONSerialization *) getTask:(id)task_id{
NSJSONSerialization *json;
NSLog(#"task id = %#", task_id);
NSString *post = [NSString stringWithFormat:#"&task_id=%#", task_id];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://www.iampeterstuart.co.uk/todo/index.php/task/get"]]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Current-Type"];
[request setHTTPBody:postData];
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES];
[conn start];
return json;
}
// Log the response for debugging
+ (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSLog(#"Resonse: %#", response);
}
+ (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data {
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSJSONSerialization *json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
}
// Declare any connection errors
+ (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"Error: %#", error);
}
Each time the variable json is null?
Could somebody please advice?
Many thanks,
Peter
You are thinking incorrectly about the delegate's behavior.
(void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data will be called whenever new data is available (downloaded from the server), which is the raw bytes of the byte stream. You should have an instance of NSMutableData and append that received data to the mutable data when data is received. Finally, when the whole data (e.g. JSON string in your example) is downloaded, -(void)connectionDidFinishLoading:(NSURLConnection *)connection will be called. In that method, you should parse the JSON string:
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSJSONSerialization *json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
...where data is the cumulative data received. You can create the data instance as below in the class implementation:
NSMutableData *cumulativeData;
In init or whatever method that is initially called on your delegate before you start loading, call:
cumulativeData = [NSMutableData data];
Then in your (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data method, call:
[cumulativeData appendData:data];
That should append the received data into the cumulative data that you are "building".
I've search and try many different solutions but without luck.
I am trying to make a JSON Request to my server, it works for sure because I've tested it in PHP (simple call, it receives string name and string password and check into the database if the user is correct). The request should receive back a JSON with property "success" only (which could be "true" or "false").
Here is my code:
- (void)logonService:(NSString *) name widthArg2:(NSString *) password {
// Create the request.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://46.51.169.145/ios/index.php/user/login/"]];
// Specify that it will be a POST request
request.HTTPMethod = #"POST";
//setting json fields
[request setValue:#"application/json; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
//prepare output data
NSString *in1;
NSDictionary *outputData = [NSDictionary dictionaryWithObjectsAndKeys:in1, #"success", nil];
NSError *error = nil;
NSData *jsonOutputData = [NSJSONSerialization dataWithJSONObject:outputData options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonOutputString = [[NSString alloc] initWithData:jsonOutputData encoding:NSUTF8StringEncoding];
//set json string to body data
NSData *requestInputBodyData = [jsonOutputString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody: requestInputBodyData];
//prepare input data
NSString *input = [NSString stringWithFormat:#"&name=%#&password=%#",name,password];
//Encode the post string using NSASCIIStringEncoding and also the post string you need to send in NSData format.
NSData *inputData = [input dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
//calculate length of post data
NSString *inputLength = [NSString stringWithFormat:#"%d",[inputData length]];
//Set HTTP header field with length of the post data.
[request setValue:inputLength forHTTPHeaderField:#"Content-Length"];
//encode type
//[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Current-Type"];
//add it to http body
[request setHTTPBody:inputData];
// Create url connection and fire request
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if(conn){
NSLog(#"Connection Successful");
}else{
NSLog(#"Connection could not be made");
}
}
The delegate DidReceiveData fires correctly but the result is always NIL:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSString *jsonResponseData = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(#"RESULT1: %#", jsonResponseData);
[_responseData appendData:data];
}
Thank you, hope someone can help me!
thanks a lot for the comments, I finally fix it, and after that I decided to starting using a JSON library --> https://github.com/stig/json-framework/
This is how I finally have the code:
//prepare connection
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#user.php", _urlServer]];
NSMutableDictionary *data = [[NSMutableDictionary alloc] init];
[data setObject:#"login" forKey:#"action"];
[data setObject:username forKey:#"username"];
[data setObject:password forKey:#"password"];
//start connection
// Create the request, if there is a connection going on just cancel it.
[_connection cancel];
//initialize new mutable data
NSMutableData *receivedData = [[NSMutableData alloc] init];
_receivedData = receivedData;
//initialize the url which will be fetched
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[url standardizedURL]];
//set http method
[request setHTTPMethod:#"POST"];
//initialize a post data
NSString *dataString = [[NSString alloc] init];
for(id key in data) {
id value = [data objectForKey:key];
//keys string
NSString *newData = [NSString stringWithFormat:#"&%#=%#", key, value];
dataString = [dataString stringByAppendingString: newData];
}
//set request content type we MUST set this value.
[request setValue:#"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
//set post data of request
[request setHTTPBody:[dataString dataUsingEncoding:NSUTF8StringEncoding]];
//initialize a connection from request
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
_connection = connection;
//NSLog(#"Sending request with parameters: %#", dataString);
//begin the connection
[_connection start];
And its working like a charm. Next step is to authenticate somehow, right now connection is open to the world.
I am having an issue trying to fetch JSON page from one of our company's site that requires authentication.
- http://xyz.com - requires authentication
- I need to fetch data from http://xyz.com/jsonpage1
- In View DidLoad, I send user and pwd for login to establish session
- Then, I have a button that would request JSON.
This sequence doesn't work (meaning if the session loading code is in a different routine than the json loading code). If I have both codes in same routine like a view didLoad, then it seems to recognize my credentials and get JSON back. Strange! What am I missing? How is supposed to work? I thought establishing the session will create the cookie one time and no need to bother with it again? Am I losing the cookie somehow when I click the button?
-(void)viewDidLoad
{
[self establishSession];
}
-(void)establishSession{
//
//Login Session
//
NSURL *url = [NSURL URLWithString:#"http://xyz.com/login"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *post = [NSString stringWithFormat:#"username=%#&password=%#",#"abc",#"123"];
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
[request setValue:[NSString stringWithFormat:#"%d",[postData length]] forHTTPHeaderField:#"Content-Length"];
[request setTimeoutInterval:15];
[request setHTTPBody:postData];
[request setHTTPMethod:#"POST"];
urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[urlConnection start];
}
- (IBAction)getJSON:(id)sender
{
NSError *error = nil;
resultsView.text =#"";
[self establishLoginSession]; //I have to have this line here to get it to work ?????
//get JSON
NSURL *jurl = [NSURL URLWithString:#"http://xyz.com/jsonPage1"];
NSData *jdata = [NSData dataWithContentsOfURL:jurl options:NSDataReadingUncached error:&error];
NSDictionary* jsonDict = [NSJSONSerialization
JSONObjectWithData:jdata //1
options:kNilOptions
error:&error];
NSString *dataString = [[NSString alloc]initWithData:jdata encoding:NSUTF8StringEncoding];
resultsView.text = dataString;
}
//Not sure if I need the cookie??
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse*) response;
NSDictionary *fields = [HTTPResponse allHeaderFields];
if([fields valueForKey:#"Set-Cookie"])
cookie = [fields valueForKey:#"Set-Cookie"];
}
You can only make one request with a NSURLConnection object, so you should create it right before you're making the request.