NSURLConnection fails sometimes - Server inaccessible? - objective-c

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!

Related

NSURLConnection doesn't send data, but connects

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.

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]

How to get an Answer from a web service after sending Get request in iOS

I'm a novice in iOS developing, and have some problems with understanding web service organization. I want to send a Get query to the URL. And I do it so:
-(BOOL) sendLoginRequest{
NSString *getAction = [NSString stringWithFormat:#"action=%#&username=%password=%#",#"login",self.log.text, self.pass.text];
NSString *getUserName = [NSString stringWithFormat:#"username=%#",self.log.text];
NSString *getPassword = [NSString stringWithFormat:#"username=%#",self.pass.text];
NSData *getDataAction = [getAction dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *getLengthAction = [NSString stringWithFormat:#"%d", [getDataAction length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:#"http:http://www.site.fi/api/"]];
[request setHTTPMethod:#"GET"];
[request setValue:getLengthAction forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:getLengthAction];
self.urlConnection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
NSAssert(self.urlConnection != nil, #"Failure to create URL connection.");
// show in the status bar that network activity is starting
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
the answer may be "true" or "false"
but how can I take this answer?
You should define next methods to get answer:
Start connection: [self.urlConnection start];
Check server response:
- (void)connection:(NSURLConnection *)theConnection didReceiveResponse:(NSURLResponse *)response
Collect data that servers sends you:
- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data
Be sure to manage errors:
- (void)connection:(NSURLConnection *)theConnection didFailWithError:(NSError *)error
Check received data:
- (void)connectionDidFinishLoading:(NSURLConnection *)theConnection
To be more sure that you correctly understood me check NSURLConnection Class Reference
Send [self.urlConnection start]; and implement the NSURLConnectionDelegate methods to receive the response. Alternatively use ASIHTTPRequest and the block handlers, which to my way of thinking are much easier to write for beginners, provided you don't need to run on iOS pre-4.1.
You will gather the data returned as NSData; just convert that to a string, and either call boolValue on the string (check the docs for its rather strange tests), or use a specific set of your own tests.

Receiving EXC_BAD_ACCESS message with the following code

I am new to Objective C, so I'm not really even sure what this message means:
EXC_BAD_ACCESS
When executing the following code:
-(void)HelloWorld
{
NSURL *url = [NSURL URLWithString:#"http://example.com/service.asmx/HelloWorld"];
NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL: url];
//do post request for parameter passing
[request setHTTPMethod:#"POST"];
//set the content type to JSON
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection release];
[request release];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Store incoming data into a string
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
I'm attempting to integrate with the Json Framework.
I call HelloWorld, which executes an async request to my service. What's strange, is that it worked one time, and now I get this EXC_BAD_ACCESS message every subsequent time. Any ideas what would be causing this?
You shouldn't be releasing the request. It's already autoreleased.
EXC_BAD_ACCESS means you have a bad pointer. In your case, it's because you are releasing the request when it's already autoreleased.
There's also another problem with your code (unrelated to the crash). You create an NSURLConnection and immediately release the connection after creation. When creating an asynchronous connection, you should release the connection in the delegate methods (if connection fails or if connection did finish loading).

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).