NSURLConnection doesn't send data, but connects - objective-c

The URL is written properly, I tested it in the browser with data and it sends properly, but when I make the request, it returns that it is successful, but it does not actually write the data. Any idea?
- (void)writeAboutMe:(NSString *)about withIcebreaker:(NSString *)icebreaker
{
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
NSString *urlString = [NSString stringWithFormat:#"http://nailorbail.net63.net/submit_about_and_icebreaker.php?username=%#&about=%#&icebreaker=%#",[SignInViewController getUsernameString] ,about,icebreaker];
NSLog(#"%#",urlString);
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Current-Type"];
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];
if(conn)
NSLog(#"Connection Successful");
else
NSLog(#"Connection could not be made");
[conn release];
}

It could be an encoding issue. What kinds of characters are in getUsernameString, about, and icebreaker? As Maudicus mentioned, you need to handle special characters in the URL yourself.
Try:
urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]

You have set up an asynchronous connection. Do you implement the NSURLConnection delegate protocol methods? Are any of them being called?
The creation of the connection instance doesn't say anything about it's success.
Check out some tutorials, like this one.

Related

NSURLConnection fails sometimes - Server inaccessible?

How can I detect if an NSURLConnection failure is due to server being inaccessible?
I checked the server's logs and there is no mention of the app's calls in these cases when the NSURLConnection failed. However, could it be that trying to initiate the NSURLConnection (see below) failed for a different reason?
I implement the call to NSURLConnection via a wrapper with the following init function:
-(id)initWithURL:(NSURL*)url
postData:(NSData*)postData
responseData:(NSMutableData*)responseData
delegate:(id)delegate
doneSelector:(SEL)doneSelector
errorSelector:(SEL)errorSelector {
if(self=[super init]) {
_url = [url retain];
_postData = [postData retain];
_responseData = [responseData retain];
_delegate = [delegate retain];
_doneSelector = doneSelector;
_errorSelector = errorSelector;
// Set up request
NSMutableURLRequest* request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:_url];
[request setHTTPMethod:#"POST"];
[request setValue:[NSString stringWithFormat:#"%d",[_postData length]] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:_postData];
// Kick off the connection
NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
if(!connection) {
[_delegate performSelector:_errorSelector];
}
}
return self;
}
We never encountered this problem during our testing (and 99% of the time the URL connection works flawlessly for our users) so I am unable to say where exactly the NSURLConnection fails. I do know though that when it fails the errorSelector is called with an empty _responseData string.
Do you see anything in the above code that may fail on rare occasions?
Any idea how to find the cause of the connection failures?
Thanks in advance!

Calling Webservice in iPhone application?

I am using soap webservice.
In that i am calling one webmethod. Here if i call from one part of my code is working fine and calling service successfully and retriving data successfully.
But if i calling same method from another part of code of same class is not responding and not getting any data from service. Why is going like that can any one help me please.
Thanks in advance
In detail.m
-(void) downloadAndParse:(NSMutableURLRequest *)sentReq {
conn = [[NSURLConnection alloc] initWithRequest:sentReq delegate:self];
if (conn) {
webData = [[NSMutableData data] retain];
}
}
-(void)fullBarcodeSearch:(NSString *)code {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
URLRequest *r = [[URLRequest alloc] init];
NSMutableURLRequest *req = [r fullBarcodeSearch:code];
[r release];
[self downloadAndParse:req];
}
In URLRequest.m
-(NSMutableURLRequest *) addHeaderToSoapXML:(NSString *) soapMsg {
NSURL *url = [NSURL URLWithString:str];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d",[soapMsg length]];
[req addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"content-type"];
[req addValue:msgLength forHTTPHeaderField:#"Content-Length"];
[req setHTTPMethod:#"POST"];
[req setHTTPBody:[soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
return req;
}
if service not called then i am getting error like this
*oid _WebThreadLockFromAnyThread(bool), 0x6958130: Obtaining the web lock from a thread other than the main thread or the web thread. UIKit should not be called from a secondary thread.*
Please any one help me
Thanks in advance
You need an NSURLConnection to execute the NSURLRequest. Lookup the Apple Docs on the class.
Something like:
[urlConnection sendSynchronousRequest:urlRequest returningResponse: &urlResponse error:&error]

Asynchronous POST to server

The goal is to do a simple username/password authentication by querying a database. Until the connection is working decently my php destination file simply has following code:
echo "Posted: " . $_POST['email'];
The code to do this synchronously is this:
NSString *post = [[NSString alloc] initWithFormat:#"email=%#&password=%#", self.email.text, ..]; // .. simplified keychainItem
NSData *postEncoded = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
NSString *postLength = [NSString stringWithFormat:#"%d", [postEncoded length]];
NSURL *url = [NSURL URLWithString:#"http://eng.studev.groept.be/web2.0/a11_web02/improver/app/testPost"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postEncoded];
NSError *error = nil;
NSURLResponse *response = nil;
NSData *encodedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *data=[[NSString alloc]initWithData:encodedData encoding:NSUTF8StringEncoding];
NSLog(#"Data? %#",data);
The correct value is shown as an echo. But when trying to do this asynchronously, I get following php error: "Undefined index: email".
I try to start the asynchronous request with this line:
[[NSURLConnection connectionWithRequest:request delegate:self] start];
Then, I have the delegate method connection:didReceiveResponse, but there I cannot seem to get the data out... Or do I need another delegate method? Also, how 'safe' is it to check the result of your query by using just an echo (do I need/want a stream maybe?) ??
Tia
EDIT
Problem related to the server, not to objective-C code. Asked a new question to reach the correct audience: $_POST remaining empty
#ott is on the right track, I'll try to clarify.
You don't need start as he says. It's benign as the connection will start automatically.
initWithRequest:delegate and connectionWithRequest:delegate: are equivalent except for the retain state of the new connection object.
The real problem is b/c you are using connectionWithRequest:delegate the returned connection is autoreleased at the end of the run loop and you are not retaining it in a property. Therefore, the connection never starts.
The solution is to add a property #property (nonatomic, retain) NSURLConnection *connection to your class and set this property to the connection returned from connection:withRequest:
You then release the connection in the completion methods connection:didFinishLoading and connection:didFailWithError:.
The start is wrong here. Simply use
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
with NSURLConnection *connection; defined. See the class reference for connectionWithRequest. start is to be used with initWithRequest:delegate:.

POST with NSURLConnection - NO JSON

I am trying to write an iPhone app in Objective-C. I need to POST data using NSURLConnection. Every example I can find deals with JSON; I do not need to use JSON. All I need to do is POST the data and get a simple 1 or 0 (succeed or fail) from a PHP script. Nothing more.
I came across this code but I am not sure how to use it or modify it to not use JSON:
- (void)performRequest {
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://someplace.com/"]];
[request setValue:#"Some Value" forHTTPHeaderField:#"Some-Header"];
[request setHTTPBody:#"{\"add_json\":\"here\"}"];
[request setHTTPMethod:#"POST"];
[NSURLConnection connectionWithRequest:[request autorelease] delegate:self];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// Fail..
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// Request performed.
}
Here's how to create an ordinary post.
First create a request of the right type:
NSURL *URL = [NSURL URLWithString:#"http://example.com/somepath"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
request.HTTPMethod = #"POST";
Now format your post data as a URL-encoded string, like this:
NSString *params = #"param1=value1&param2=value2&etc...";
Remember to encode the individual parameters using percent encoding. You can't entirely rely on the NSString stringByAddingPercentEscapesUsingEncoding method for this (google to find out why) but it's a good start.
Now we add the post data to your request:
NSData *data = [params dataUsingEncoding:NSUTF8StringEncoding];
[request addValue:#"8bit" forHTTPHeaderField:#"Content-Transfer-Encoding"];
[request addValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request addValue:[NSString stringWithFormat:#"%i", [data length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:data];
And that's it, now just send your request as normal using NSURLConnection (or whatever).
To interpret the response that comes back, see Maudicus's answer.
You can use the following NSURLConnection method if you target ios 2.0 - 4.3 (It seems to be deprecated in ios 5)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSString * string = [[NSString alloc] initWithData:data encoding:
NSASCIIStringEncoding];
if (string.intValue == 1) {
} else {
}
}
I've a very similar situation to whitebreadb. I'm not disagreeing with the answers submitted and accepted but would like to post my own as the code provided here didn't work for me (my PHP script reported the submitted parameter as a zero-length string) but I did find this question that helped.
I used this to perform a posting to my PHP script:
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"http://www.myphpscriptlocation.net/index.php?userID=%#",self.userID_field.stringValue]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
request.HTTPMethod = #"POST";
NSURLConnection *c = [NSURLConnection connectionWithRequest:request delegate:self];

NSURLConnection POST also calls GET of same URL

I have a NSURLConnection which is a post to the server, but I expect it to return some small data, whether it was successful or not.
-(void)submitPost:(NSString *)xml
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[service generateURL]];
NSString *result = (NSString *) CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)xml, NULL, CFSTR("?=&+"), kCFStringEncodingUTF8);
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:[result dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPMethod:#"POST"];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
if(theConnection)
{
NSLog(#"Connection success");
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[theConnection retain];
failed = NO;
}
else
{
NSLog(#"Connection failed");
}
}
The problem is, not only does it send a post the URL, it also sends a GET, and the GET response is returned as the data... I'm a bit confused. I checked my wireshark output, and it's definitely making both a post and a get.
What do you guys think?
Does the URL respond to a POST with redirect? You can implement the NSURLConnection delegate method connection:willSendRequest:redirectResponse: to see if that's the case (and to cancel an unwanted redirect).