Can't seem to get response from POST with NSURLConnection - ios

I have search around and can't quite find the right answer to this, but I have this code which posts data to my web server, and I am trying to get the HTTP response, but the response keeps returning (null). I can confirm that the connection is successful because the if statement (see below) executes the appropriate code.
Here is my code:
-(void)submitAction{
NSString *post = [NSString stringWithFormat:#"&var1=%#&var2=%#&var3=%#&var4=%#",
_var1, _var2, _var3, _var4];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d",[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://my-web-server.com/path-to-web-service/"]]];
[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];
NSURLResponse *response;
NSLog(#"%#", response); // Always returns null :(
if(conn){
NSLog(#"Connection Successful."); // Connection is successful in my tests.
}else{
NSLog(#"Connection could not be made");
}
}
Here is the NSURLConnectionDelegate delegate implemented in my .h file:
#interface AddTaskViewController : UIViewController <UITextFieldDelegate, UIPickerViewDelegate, NSURLConnectionDelegate>
Can anyone see what I am doing wrong here? The server should return a JSON string, (and it does when I test the web service via my browser) but the NSURLResponse is constantly null.
Thanks,
Peter

Using initWithRequest:delegate: of NSURLConnection starts an asynchronous download, so it returns immediately and executes straight away.
response is always nil because you just defined it and then logged it without ever setting it to anything. That needs to be done in the connection:didReceiveResponse: delegate method.
Where you do if(conn){, the conn existing doesn't mean the connection was successful, it just means that the connection could be created (basically, you didn't supply an invalid request). You don't know whether it's going to work yet.
Implement the delegate methods from NSURLConnectionDelegate_Protocol (and NSURLConnectionDataDelegate) to get access to the response and downloaded data (when it becomes available).

Related

Not able to figure out why data posted twice to a api in iOS?

I'm building an iOS app and posting a data to api. I'm facing a problem that i posted a once
but it is reflected twice on the server.And i have checked from rest clients that there is no error at the server side.
here is my code
- (void) next: (UIButton*) sender
{
NSString *post =[NSString stringWithFormat:#"? &sportsname=%#&time=%#&venue=%#&date=%#&players=%#&addinfo=%#&userid=%#&gender=%#&recurring=%#",_selectedSport,_selectedTime,location,dateValue,max,info,UserId,_selectedGender,_selectedRecurring];
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://yy.4.yyy.hh:iyiy/api/user/%#/host",UserId]]];
[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];
[self performSegueWithIdentifier:#"hostSubmit" sender:nil];
if(conn)
{
NSLog(#"Connection successfull");
}
else
{
NSLog(#"connection could not be made");
}
}
It's pretty easy to link the same action twice in a button. Look at the actions tab in interface builder and make sure you haven't linked your button to your next: action twice.
Failing that, add a log statement at the beginning of the method "entering method 'next:'" and see if you see the log twice. If you do, go figure out why.

HTTP Status 500 - Request processing failed

I am tried to Post String value to Sql Server.like this
NSString *post =[NSString stringWithFormat:#"?&name=%#&password=%#&pin=%#&email=%#&phone=%#&address=%#&city=%#&status=%#",
name, password ,pin ,email ,phone,address,city,status];
NSLog(#"post%#",post);
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d",[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://202.65.154.108:8080/SaveDollar/rest/deals/add"]]];
NSLog(#"getData%#",request);
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Current-Type"];
[request setHTTPBody:postData];
NSLog(#"getData%#",request);
con3 = [[NSURLConnection alloc]initWithRequest:request delegate:self];
if(con3)
{ webData3=[NSMutableData data];
NSLog(#"Connection successful");
NSLog(#"GOOD Day My data %#",webData3);
}
else
{
NSLog(#"connection could not be made");
}
I tried like this connection successful.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSString *responseText = [[NSString alloc] initWithData:webData3 encoding: NSASCIIStringEncoding];
NSLog(#"Response: %#", responseText);}
But get Response like this HTTP Status 500 - Request processing failed; nested exception is java.lang.NullPointerException
I am not understand What my mistake so Please give me any idea,and Please tell me What wrong in my code.
Thanks in Advanced .
5xx Server Error
HTTP 500 Internal Server Error
A generic error message, given when an unexpected condition was encountered and no more specific message is suitable. Source of this Wikipedia : - List of HTTP status codes and w3.org Status codes
So need to check on server side. It's not your issue.
HTTP 500 Internal error (or) internal server error
It is meant that the error may be on several reasons
- The fault may be from server side i.e Json
- The fault may be from your side in which the parameters which you are sending may be in correct format which is expected from server
- The fault may be coding side which leads to crash

NSURLRequest not posting values to a Codeigniter API

Good day,
I am trying to use a Codeigniter based API to connect with iOS and using NSURLRequest.
The API is in debugMode and for now it returns the same key value pair as json as the one that you are posting. I have tried posting the values to the link through postman and it works correctly, however when I post it through my iOS application, the json response is received but the array that should contain the post values is empty.
Here is the iOS Code snippet :
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#",BASEURL,service]];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
NSURLConnection *connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSString * params = #"authkey=waris";
NSData * postData = [params dataUsingEncoding:NSUTF8StringEncoding];
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"content-type"];;
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
NSLog(#"Posting : '%#' to %#",params,url);
[connection start];
This is the response when I post the same parameters through postman ( A RESTFUL Client for Chrome )
{
"status": "1",
"data": {
"authkey": "warisali"
}
}
However when I query the same API from the above iOS Code I am getting this :
{
data = 0;
status = 1;
}
Any help on the matter will be highly appreciated!
I had same issue (not with CodeIgniter but with Ruby ...)
Try something like this, solved my problem.
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#",BASEURL,service]];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
NSURLConnection *connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSDictionary *paramDict = #{#"authkey": #"waris"};
NSError *error = nil;
NSData *postData = [NSJSONSerialization dataWithJSONObject:paramDict options:NSJSONWritingPrettyPrinted error:&error];
if (error)
{
NSLog(#"error while creating data %#", error);
return;
}
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];;
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
NSLog(#"Posting : '%#' to %#",params,url);
[connection start];
I ended up using the ASIHttpRequest + SBJson combo and that worked like Charm!
After adding the ASIHttpRequest core classes and SBJson Classes to parse the JSON, I was able to achieve what I wanted !
The problem is that because of the way you're creating the connection, it will start immediately, before you've finished configuring the request. Thus, you're creating a mutable request, creating and starting the connection, then attempting to modify the request and then trying to start the request a second time.
You can fix that by changing the line that says:
NSURLConnection *connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
To say:
NSURLConnection *connection=[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
Or, easier, just move the original instantiation of the NSURLConnection (without the startImmediately:NO) after you've finished configuring your request, and then eliminate the [connection start] line altogether.

Timeout in NSURLConnection to WCF JSON REST server

I have a Windows based REST Server built using Microsoft-HTTPAPI (i.e. its not running under IIS)
If I send a JSON request to the service from a browser based REST tool (Firefox RESTClient) the server receives the request and processes it correctly as per the traces from the Microsoft Service Trace Viewer and the response from the service. I receive valid JSON back from the service.
I have an iOS application that uses a NSURLConnect to send the VERY SAME JSON request to the service, but it always times out. I've traced using WireShark, and the HTTP request is correctly formed and sent correctly to the server in both cases. I've traced using the MS Trace Viewer and it goes into "receive Bytes" but never returns. I get an exception when I eventually close the WCF Server.It never returns when I close the iOS app.
I have tried using NSURLConnection sendSynchronousRequest and asynchronously using the callbacks and asynchronously using completion blocks. If I make the timeout 0, the call (to sendSynchronousRequest) never returns. In all other cases, I get a timeout, and the WCF never completes the receive bytes part of the WCF invocation (a POST request)
I've checked
Here's my iOS Code:
dispatch_queue_t myQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(myQ, ^{ // First Queue the parsing
#try {
//Generate endpoint url
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#/%#",appState.posPostingURL,serviceName]];
//Setup request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:10.0];
NSString *authStr = [NSString stringWithFormat:#"%#:%#", #"xxxx", #"xxxx"];
NSString *authData = [NSString base64StringFromString:authStr];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", authData];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
//Setup request headers
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"no-cache" forHTTPHeaderField:#"Cache-Control"];
[request setValue:[NSString stringWithFormat:#"%d", [dataBuffer length]] forHTTPHeaderField:#"Content-Length"];
// Put the request data in the request body
[request setHTTPBody: dataBuffer];
NSHTTPURLResponse *urlResponse = nil;
NSError *error = nil;
// and send to the server synchronously
serverData = [[NSURLConnection sendSynchronousRequest:request
returningResponse:&urlResponse
error:&error] mutableCopy];
// Now check the status and response
if (error) {
My WCF Code is as follows
namespace MyWebService{
[ServiceContract(Name = "MyServiceIntegrator", Namespace = "")]
public interface IMyIntegrator
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/Configure",
BodyStyle=WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
Result Configure(MyServerConfig config);
In the app.config file, the service endpoint is configured with
binding="webHttpBinding"
The Trace view is as follows:
Could there be any reason on either side that the server does not complete the read even though the JSON is valid.
I have also checked NSURLConnection JSON Submit to Server
and as far as I can see my code to send the request is correct.
Any ideas - Been pulling my hair out for 3 days now
What happens if you change this:
[request setValue:[NSString stringWithFormat:#"%d", [dataBuffer length]] forHTTPHeaderField:#"Content-Length"];
To this:
[request setValue:[NSString stringWithFormat:#"%i", [dataBuffer length]] forHTTPHeaderField:#"Content-Length"];
Probably won't make a difference, but the rest of your code looks fine so maybe worth a shot. (My thinking is the decimal is causing the server issues).
ferdil,I think you can try changing timeout period to 30.0 instead of 10.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:30.0];

NSURLConnection, Login then Post Image

I'm trying to upload a picture to my website from my iPhone, but I need to authenticate first.
My first attempt was to send an HTTP Post request with my login credentials using NSMutableURLRequest, and then sending the image in a similar fashion with a second NSMutableURLRequest (in a separate NSURLConnection). But that failed since no session data was kept from the login to the image post. I still got auth errors on the second request.
I thought I would be clever and create a hidden UIWebView and just call [webview loadRequest:request]; for both login and then post image, where request is of type NSMutableURLRequest. This worked great and now I'm able to upload images to my website.....
....However, when I tried on my iPod touch, I get the infamous received memory warning followed by an app crash when I call [webview loadRequest:request]; I'm only allocating about 10MB of memory for the entire app (thanks to profiler) so my guess it it's not in the request itself, but how UIWebView handles it. I think the "view" part of the UIWebivew is allocating a lot of memory.
Here's my question: how do I persist the session and login data between NSURLConnections so that I don't have to use a UIWebView?
pseudocode:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:YES];
[request setTimeoutInterval:180];
[request setHTTPMethod:#"POST"];
[ request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"content-type"];
NSURL* url = [[NSURL alloc]initWithString:#"http://website.com/login.php"];
NSMutableData *body = [NSMutableData data];
[body appendData:[#"username=me&password=password&" dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
NSString *postLength = [NSString stringWithFormat:#"%d", [body length]];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setURL:url];
Then:
[self.webview loadRequest:request];
Or:
NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (connection) {
NSLog(#"Login Opened");
responseData = [NSMutableData data];
} else {
NSLog(#"Logon failed");
}
Authentication depends on correct functioning of cookies. It looks like you are using the web view's loadRequest for one of your requests. If you just use NSURLConnection for both requests, it should correctly manage reading the cookie from the first response and sending it in the second request on your behalf. (See the URL Loading System Programming Guide.) If this still isn't working, then there may be a problem with your session cookie settings on your server.

Resources