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".
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;
}
Little issue that's been bothering me. I've been making a POST request to my AWS RDB. The request should return a json output. The issue I'm having is that I'll receive bytes back, but sometimes it contains incomplete json, thus converting it to a dictionary won't work. Sometimes I also receive a null value for the nsdata received, but I can print out the length of the data. Any ideas? Here's my iOS code for requests:
#import "ServiceConnector.h"
#implementation ServiceConnector{
NSMutableData *receivedData;
}
-(void)getTest{
//Send to server
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"MY_WEBSITE"]];
[request setHTTPMethod:#"GET"];
//initialize an NSURLConnection with the request
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if(!connection){
NSLog(#"Connection Failed");
}
}
-(void)postTest:(NSMutableArray *)carSearches{
//build up the request that is to be sent to the server
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"MY_WEBSITE"]];
[request setHTTPMethod:#"POST"];
NSError *writeError = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:carSearches options:NSJSONWritingPrettyPrinted error:&writeError];
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"JSON Output: %#", jsonString);
[request setHTTPBody:data]; //set the data as the post body
[request addValue:[NSString stringWithFormat:#"%lu",(unsigned long)data.length] forHTTPHeaderField:#"Content-Length"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if(!connection){
NSLog(#"Connection Failed");
}
}
#pragma mark - Data connection delegate -
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ // executed when the connection receives data
if(!receivedData){
receivedData = [[NSMutableData alloc]init];
[receivedData appendData:data];
}
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ //executed when the connection fails
NSLog(#"Connection failed with error: %#",error);
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(#"Request Complete,recieved %lu bytes of data",(unsigned long)receivedData.length);
NSString *tmp = [NSString stringWithUTF8String:[receivedData bytes]];
NSLog(#"%#",tmp);
NSError *error;
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:[NSData dataWithBytes:[receivedData bytes] length:[receivedData length]] options:NSJSONReadingAllowFragments error:&error];
[self.delegate requestReturnedData:dictionary];
}
In this section:
if(!receivedData){
receivedData = [[NSMutableData alloc]init];
[receivedData appendData:data];
}
You are only appending data if the object hasn't been created yet. You want to append every time. That if statement should read like this:
if(!receivedData){
receivedData = [[NSMutableData alloc]init];
}
[receivedData appendData:data];
I have a post method that looks like this:
NSString *totalPostURL = [NSString stringWithFormat:#"%#registerDevice",self.textUrl];
NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:[NSURL URLWithString:totalPostURL]];
NSError *error;
NSData *postData = [NSJSONSerialization dataWithJSONObject:self.finalDict options:0 error:&error];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
The code works fine but I have no idea how to print the response from this post. Any suggestions welcome as I'm new to iOS development.
You can print the response as below:
NSData *returnData = [ NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil ];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];
NSLog(#"Response:%#",returnString);
But Remember as you are a newbie,don't forget to read the tutorial for calling webservices.Interacting with webservices.
You get your response in the connection delegate. Look for the method
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Append the new data to receivedData.
// receivedData is an instance variable declared elsewhere.
[receivedData appendData:data];
}
You can use like this...
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[receivedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *jsonString = [[NSString alloc] initWithString: receivedData];
NSData* cData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *WSerror;
NSDictionary *responseDic = [NSJSONSerialization JSONObjectWithData:cData options:NSJSONReadingAllowFragments error:&WSerror];
}
Print the responseDic.
#Ayan Khan is right! here i'm adding sample code for http post print response and parsing as JSON if possible, it will handle everything async so your GUI will be refreshing just fine and will not freeze at all - which is important to notice.
//POST DATA
NSString *theBody = [NSString stringWithFormat:#"parameter=%#",YOUR_VAR_HERE];
NSData *bodyData = [theBody dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
//URL CONFIG
NSString *serverURL = #"https://your-website-here.com";
NSString *downloadUrl = [NSString stringWithFormat:#"%#/your-friendly-url-here/json",serverURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString: downloadUrl]];
//POST DATA SETUP
[request setHTTPMethod:#"POST"];
[request setHTTPBody:bodyData];
//DEBUG MESSAGE
NSLog(#"Trying to call ws %#",downloadUrl);
//EXEC CALL
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error) {
NSLog(#"Download Error:%#",error.description);
}
if (data) {
//
// THIS CODE IS FOR PRINTING THE RESPONSE
//
NSString *returnString = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];
NSLog(#"Response:%#",returnString);
//PARSE JSON RESPONSE
NSDictionary *json_response = [NSJSONSerialization JSONObjectWithData:data
options:0
error:NULL];
if ( json_response ) {
if ( [json_response isKindOfClass:[NSDictionary class]] ) {
// do dictionary things
for ( NSString *key in [json_response allKeys] ) {
NSLog(#"%#: %#", key, json_response[key]);
}
}
else if ( [json_response isKindOfClass:[NSArray class]] ) {
NSLog(#"%#",json_response);
}
}
else {
NSLog(#"Error serializing JSON: %#", error);
NSLog(#"RAW RESPONSE: %#",data);
NSString *returnString2 = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];
NSLog(#"Response:%#",returnString2);
}
}
}];
Hope this helps!
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 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]];