Anyone noticed images fail to load after network interruption? - iphone

I just noticed that when you get a network interruption the code proposed by Apple fails to load the images ... It works perfectly otherwise though ;)
It is due to the fact that IconDownloader doesn't do anything if NSURL connection fails ...
Before I struggle with this on my own, anyone has any tips for me :D ?
Thanks a lot,
Gotye.

==> i think this is what we can do to download if nsurlconnection method get fail with connection
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
// Clear the activeDownload property to allow later attempts
self.activeDownload = nil;
// Release the connection now that it's finished
self.imageConnection = nil;
//i think we can call the connection method again from here
self.activeDownload = [NSMutableData data];
// alloc+init and start an NSURLConnection; release on completion/failure
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:
[NSURLRequest requestWithURL:
[NSURL URLWithString:appRecord.imageURLString]] delegate:self];
self.imageConnection = conn;
[conn release];
}

Related

NSURLConnection doesn't receive data

I have implemented an NSURLConnection that sends a request to a server and receives some data back which is stored in an NSMutableData object. These are the methods that I implemented as part of NSURLConnectionDelegate:
-(void)upLoadBook:(NSMutableDictionary *)theOptions{
NSMutableString *theURL = [[NSMutableString alloc] initWithString:#"theURL"];
[theURL appendFormat:#"&Title=%#&Author=%#&Price=%#", [theOptions objectForKey:#"bookTitle"],
[theOptions objectForKey:#"bookAuthor"],
[theOptions objectForKey:#"bookPrice"]];
[theURL appendFormat:#"&Edition=%#&Condition=%#&Owner=%#", [theOptions objectForKey:#"bookEdition"],
[theOptions objectForKey:#"bookCondition"],
_appDel.userID];
NSLog(#"%#\n", theURL);
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:theURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
receivedData = [NSMutableData data];
}
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse
*)response
{
// This method is called when the server has determined that it
// has enough information to create the NSURLResponse.
// It can be called multiple times, for example in the case of a
// redirect, so each time we reset the data.
// receivedData is an instance variable declared elsewhere.
[receivedData setLength:0];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do something with the data
// receivedData is declared as a method instance elsewhere
//Receives a response after book has been uploaded (Preferably a Book ID...)
responseString = [[NSString alloc] initWithData:receivedData
encoding:NSUTF8StringEncoding];
NSLog(#"Response String: %#", responseString);
[_options setValue:responseString forKey:#"bookID"];
[self performSegueWithIdentifier:#"UploadSuccessSegue" sender:self];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Whoops." message:#" No internet
connection.\n Please make sure you have a connection to the internet."
delegate:self cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
}
The function uploadBook seems to be called,however, I never get to didFinishLoading and didReceiveData never receives any data. What could be a possible problem. Any hints or clues would be much appreciated.
You need to add your NSURLConnection to the current run loop or a separate one (such as one you set up in a separate thread). The delegate methods do need to get CPU time, after all.
Looking at this related question's accepted answer, it can also be done via Grand Central Dispatch:
dispatch_async(dispatch_get_main_queue(), ^{
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
[conn start];
});
One thing for sure is that you should %-escape your list of parameter before trying to send the request.
You can use stringByAddingPercentEscapesUsingEncoding for that purpose:
NSMutableString *theURL = [[NSMutableString alloc] initWithString:#""];
[theURL appendFormat:#"&Title=%#&Author=%#&Price=%#", [theOptions objectForKey:#"bookTitle"],
[theOptions objectForKey:#"bookAuthor"],
[theOptions objectForKey:#"bookPrice"]];
[theURL appendFormat:#"&Edition=%#&Condition=%#&Owner=%#", [theOptions objectForKey:#"bookEdition"],
[theOptions objectForKey:#"bookCondition"],
_appDel.userID];
theURL = [NSStringWithFormat:#"YOUR_URL_HERE?",[theURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
Please, note that I refactored your code with the minimum number of changes to get the result. You can find better refactorizations for sure.
Here is a sample that works from one of my projects:
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.brayden.me/analytics/device.php"]];
[urlRequest setHTTPMethod:#"POST"];
NSMutableString *postParams = [NSMutableString string];
[postParams appendFormat:#"session=%#&", analyticsSession];
[postParams appendFormat:#"device=%#&", device];
[postParams appendFormat:#"system=%#&", csystem];
[postParams appendFormat:#"version=%#&", version];
[postParams appendFormat:#"launch=%f&", totalLaunchTime];
if([Analytics_Location location].latitude && [Analytics_Location location].longitude) {
[postParams appendFormat:#"latitude=%#&", [Analytics_Location location].latitude];
[postParams appendFormat:#"longitude=%#&", [Analytics_Location location].longitude];
}
[urlRequest setHTTPBody:[postParams dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self startImmediately:YES];
[connection start];
Make sure your header method also uses . The code of mine should at least show you how to properly format the request, as I can verify this does receive data from a PHP call of mine.

NSUrlConnectionDelegate not calling methods to load data

I have looked at NSURLConnectionDelegate connection:didReceiveData not working already, but there didn't seem to be any good result from that, so I am curious why I am not able to get any data.
I put in breakpoints in didReceiveResponse and didReceiveData.
It does print out "connection succeeded", so I know that the connection is started.
I am using ARC for memory management.
- (void)load {
request = [NSMutableURLRequest requestWithURL:myURL
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (conn) {
[conn start];
NSLog(#"connection succeeded, %s", [myURL description]);
responseData = [NSMutableData data];
} else {
NSLog(#"connection failed");
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
UPDATE:
To see how I test this look at Asynchronous unit test not being called by SenTestCase.
I did implement the two methods mentioned by jonkroll, in his answer, I just didn't show them, but, they also aren't being called.
I had added [conn start] only because it wasn't working, and I was hoping that may solve it, but no such luck.
When you declare your connection like this:
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
You are creating a local pointer. When your method completes, since it was the last strong reference to the NSURLConnection, ARC releases it. You need to use a strong ivar (and/or) property to hold a strong reference to the NSURLConnection you create.
Edit
Here is basic sample of code that I tested in a sample project. Give it a run. Verbose logging helps.
#implementation <#Your class here#> {
// With ARC ivars are strong by default
NSMutableData *_downloadedData;
NSURLConnection *_connection;
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSHTTPURLResponse *realResponse = (NSHTTPURLResponse *)response;
if (realResponse.statusCode == 200){
// Really any 2** but for example
_downloadedData = [[NSMutableData alloc] init];
NSLog(#"Good response");
} else {
NSLog(#"Bad response = %i",realResponse.statusCode);
}
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
if (connection == _connection){
[_downloadedData appendData:data];
NSLog(#"Getting data...");
}
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
if (connection == _connection){
_connection = nil;
NSLog(#"We're done, inform the UI or the delegates");
}
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
_connection = nil;
NSLog(#"Oh no! Error:%#",error.localizedDescription);
}
- (void)load {
NSURL *url = [NSURL URLWithString:#"http://www.google.com/"];
NSURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60];
// Assign strong pointer to new connection
_connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(#"Connection was initialized? = %#",(!!_connection)?#"YES":#"NO");
}
#end
The NSURLConnection method initWithRequest starts an asynchronous request for data from a url. Because the request is done asynchronously you can't expect to work with the response in the same method in which the request is invoked. Instead you need to do so in the NSURLConnection's delegate callback methods. You have already implemented didReceiveResponse: and didReceiveData:, but there are a couple others that will be useful to you.
If you want to look at the contents of the response you should do so in connectionDidFinishLoading:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// response is complete, do something with the data
NSLog(#"%#", responseData);
}
The fact that your code prints out "connection succeeded" doesn't really mean that the request was successful, only that the NSURLConnection object was created successfully. To test whether there was a problem with the connection you can implement the delegate method connection:didFailWithError:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"Connection failed! Error - %# %#",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
Also there is no need to call [conn start]. The request will be started automatically when you call initWithRequest:
I suggest reading Apple's documentation on Using NSURLConnection for more details.

NSURLConnection not responding

I'm trying to get some data from an URL, but for some reason, nothing happens when I do the following. Neither didReceiveResponse:, didReceiveData:, didFailWithError: or connectionDidFinishLoading: are reached, except when I add a timeout to my request by doing this: [request setTimeoutInterval:10.0]
Here's what I'm doing :
-(void)getConfigFromServer{
[self getContentAtURL:kUrlGetUser];
}
//Va chercher le contenu à l'URL passée en paramètre
- (void)getContentAtURL: (NSURL *)url {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString * userLogin = [userDefaults objectForKey:#"UserLogin"];
NSString * userPassword = [userDefaults objectForKey:#"UserPassword"];
NSURL * urlFinal = [NSURL URLWithString:[NSString stringWithFormat:#"%#", url]];
NSLog(#"Request : %#", [NSString stringWithFormat:#"%#", url]);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:urlFinal];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:10.0];
NSString *sourceString = [NSString stringWithFormat:#"%#:%#", userLogin, userPassword];
NSData * sourceData = [sourceString dataUsingEncoding:NSUTF8StringEncoding];
NSString *authString = [sourceData base64EncodedString];
authString = [NSString stringWithFormat: #"Basic %#", authString];
[request setValue:authString forHTTPHeaderField:#"Authorization"];
[request setValue:#"text/xml" forHTTPHeaderField:#"Accept"];
NSURLConnection * connection=[NSURLConnection connectionWithRequest:request delegate:self];
if(connection){
NSLog(#"Connection started");
receivedData = [NSMutableData data];
}else{
NSLog(#"Error while trying to initiate the connection");
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[receivedData setLength:0];
if ([response respondsToSelector:#selector(statusCode)])
{
int statusCode = [((NSHTTPURLResponse *)response) statusCode];
if (statusCode >= 400)
{
[connection cancel]; // stop connecting; no more delegate messages
NSDictionary *errorInfo
= [NSDictionary dictionaryWithObject:[NSString stringWithFormat:
NSLocalizedString(#"Server returned status code %d",#""),
statusCode]
forKey:NSLocalizedDescriptionKey];
NSError *statusError = [NSError errorWithDomain:#"Error"
code:statusCode
userInfo:errorInfo];
[self connection:connection didFailWithError:statusError];
}
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSLog(#"Connection failed! Error - %# %#",[error localizedDescription],[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[self fetchedData:receivedData];
}
EDIT : I'm still having this problem, and now have it on the actual device too. As I said it in the comments, I use ARC on this app for the first time, and I'm using XCode 4.2.
Any idea?
This is old thread but still this answer might help someone out there.
If you are calling this in background thread, check whether you thread is exiting before delegates is called.
Try doing this.
NSURLConnection * connection = [[NSURLConnection alloc]
initWithRequest:request
delegate:self startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop mainRunLoop]
forMode:NSDefaultRunLoopMode];
[connection start];
Error message, as you have told in comments, is saying that the request has timed out.
I am sure that if you remove the line with timeout, you will get either the same response or actual data, after 60 seconds. Make sure you wait enough, because if your connection is very weak for some reason, the request may not time out after 60 seconds because it keeps downloading data.
Is your app in foreground while you launch this? Make sure you don't suspend it.
Furthermore, you say that the server is online, but your code is timing out. Means something is probably wrong with your connection after all.
In another comment you say that sometimes it works. Even more points to the fact that the connection is weak/unreliable or breaking up.
You're passing an NSURL to your getContentAtURL but then treating it as though it was a string in :
NSURL * urlFinal = [NSURL URLWithString:[NSString stringWithFormat:#"%#", url]];
try changing it to:
NSURL * urlFinal = [NSURL URLWithString:[NSString stringWithFormat:#"%#", [url absoluteString]]];
btw, you know you're not using your login and password don't you?
EDIT:
When you say receivedData = [NSMutableData data]; what is data?
I think that might be the problem.
I tend to use the following to setup the data object when data first arrives:
- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData {
if (receivedData ==nil) { receivedData = [[NSMutableData alloc] initWithCapacity:2048]; }
[receivedData appendData:incrementalData];
}
Some thoughts here:
Please do not store passwords in UserDefaults, use the keychain for that (maybe you are only testing, I just wanted to have this mentioned)
Why do you convert your NSURL url to a new NSURL by calling stringWithFormat: on the url? (Oh, I see #ade already mentioned that)
Is this an ARC-enabled App? If not, your NSMutableData will be autoreleased too soon, use self.receivedData = [NSMutableData data] and you will see a crash.
Try making your NSURLConnection an instance variable and hold on to it. I think it should work the way you do it right now, but I tend to hold on to it and never had the problem you mention here.
Weird that your 10 seconds timeout seems to work, I had trouble getting this to work and found that on iPhone, the timeout can not be lower than 240 seconds. Yes, I was confused about this as well, but: https://stackoverflow.com/a/3611383/148335
I think the problem will be with server side. Try to increase TimeoutInterval to 60 so there will be more time to fetch data from server. Didn't you get "connection timed out" message after 10 seconds?
EDIT
Hi, I think still you are not reached a solution. When I read the code in detail, I found some statements are confusing.
1) [request setValue:#"text/xml" forHTTPHeaderField:#"Accept"]; replace with
[request setValue:#"text/plain" forHTTPHeaderField:#"Accept"];
Also include,
[request setValue:#"text/plain" forHTTPHeaderField:#"Content-Type"];
And finally...
The error "connection timed out" indicates that the iPhone does not receiving any data from server. As soon as iPhone gets a bye of data it will call - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data. Try to put NSLog after each statements to verify variables hold desired value. Try to check the length of data --sourceData-- before sending ...

Synchonous SSL certificate handling on iPhone

I was wondering if anyone can help me understand how to add SSL certificate handling to synchronous
connections to a https service.
I know how to do this with asynchronous connections but not synchronous.
NSString *URLpath = #"https://mydomain.com/";
NSURL *myURL = [[NSURL alloc] initWithString:URLpath];
NSMutableURLRequest *myURLRequest = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
[myURL release];
[myURLRequest setHTTPMethod:#"POST"];
NSString *httpBodystr = #"setting1=1";
[myURLRequest setHTTPBody:[httpBodystr dataUsingEncoding:NSUTF8StringEncoding]];
NSHTTPURLResponse* myURLResponse;
NSError* myError;
NSData* myDataResult = [NSURLConnection sendSynchronousRequest:myURLRequest returningResponse:&myURLResponse error:&myError];
//I guess I am meant to put some SSL handling code here
Thank you.
Using the static sendSynchronousRequest function is not posible, but i found an alternative.
First of all NSURLConnectionDataDelegate object like this one
FailCertificateDelegate.h
#interface FailCertificateDelegate : NSObject <NSURLConnectionDataDelegate>
#property(atomic,retain)NSCondition *downloaded;
#property(nonatomic,retain)NSData *dataDownloaded;
-(NSData *)getData;
#end
FailCertificateDelegate.m
#import "FailCertificateDelegate.h"
#implementation FailCertificateDelegate
#synthesize dataDownloaded,downloaded;
-(id)init{
self = [super init];
if (self){
dataDownloaded=nil;
downloaded=[[NSCondition alloc] init];
}
return self;
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace: (NSURLProtectionSpace *)protectionSpace {
NSLog(#"canAuthenticateAgainstProtectionSpace:");
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge {
NSLog(#"didReceiveAuthenticationChallenge:");
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[downloaded signal];
[downloaded unlock];
self.hasFinnishLoading = YES;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[dataDownloaded appendData:data];
[downloaded lock];
}
-(NSData *)getData{
if (!self.hasFinnishLoading){
[downloaded lock];
[downloaded wait];
[downloaded unlock];
}
return dataDownloaded;
}
#end
And for use it
FailCertificateDelegate *fcd=[[FailCertificateDelegate alloc] init];
NSURLConnection *c=[[NSURLConnection alloc] initWithRequest:request delegate:fcd startImmediately:NO];
[c setDelegateQueue:[[NSOperationQueue alloc] init]];
[c start];
NSData *d=[fcd getData];
Now you will have all benefits of have an async use of nsurlconnection and benefits of a simple sync connection, the thread will be blocked until you download all data on the delegate, but you could improve it adding some error control on FailCertificateDelegate class
EDIT: fix for big data. based on Nikolay DS comment. Thanks a lot
I had a similar issue. In my case i had an a-synchronous connection working with ssl as required using the two delegate methods that allowed me to accept any certificate:
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}
But i was stuck on doing the same in a synchronous manner. I searched the web until i found your post and unfortunately another stackoverflow post where it is hinted that you cannot perform synch calls on NSURLConnection and work with ssl (because of the lack of a delegate to handle the ssl authentication process).
What i ended up doing is getting ASIHTTPRequest and using that. It was painless to do and took me about an hour to set up and its working perfectly. here is how i use it.
+ (NSString *) getSynchronously:(NSDictionary *)parameters {
NSURL *url = [NSURL URLWithString:#"https://localhost:8443/MyApp/";
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
NSString *parameterJSONString = [parameters JSONRepresentation];
[request appendPostString:parameterJSONString];
[request addRequestHeader:#"User-Agent" value:#"MyAgent"];
request.timeOutSeconds = CONNECTION_TIME_OUT_INTERVAL;
[request setValidatesSecureCertificate:NO];
[request startSynchronous];
NSString *responseString = [request responseString];
if (request.error) {
NSLog(#"Server connection failed: %#", [request.error localizedDescription]);
} else {
NSLog(#"Server response: %#", responseString);
}
return responseString;
}
The important part of course is the
[request setValidatesSecureCertificate:NO];
Another alternative for you is to handle the download in another thread with an a-synch connection using the two methods above and block the thread from which you want the synch connection until the request is complete
Im close to finding the solution for this with the code below. This works but often crashes
probably because I am doing something wrong in the way I code this and I don't have a strong understanding of the methods used. But if anyone has any suggestions on how to improve this
than please post.
Just after the line:
NSError* myError;
and just before the line:
NSData* myDataResult = [NSURLConnection sendSynchronousRequest:myURLRequest
returningResponse:&myURLResponse error:&myError];
add:
int failureCount = 0;
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
initWithHost:#"mydomain.com" port:443 protocol:#"https" realm:nil
authenticationMethod:NSURLAuthenticationMethodServerTrust];
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:myURL MIMEType:#"text/html"
expectedContentLength:-1 textEncodingName:nil];
NSURLAuthenticationChallenge *challange = [[NSURLAuthenticationChallenge alloc]
initWithProtectionSpace:protectionSpace proposedCredential:[NSURLCredential
credentialForTrust:protectionSpace.serverTrust] previousFailureCount:failureCount
failureResponse:response error:myError sender:nil];

"-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data" not called

Have a look to this code snippet:-
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[webData setLength: 0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(#"Recieving Data...");
[webData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"ERROR with theConenction");
[connection release];
[webData release];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"DONE. Received Bytes: %d", [webData length]);
NSLog(theXML);
}
I am calling a SOAP web service.There are no errors or warnings displayed in my code.
When I hit the web service through safari it works fine. But the problem arises when I try
hit it through my codes.
Everything works fine but the connection:didRecieveData does not gets called.
Thus, I get no data in the webData variable. This webData is a NSMutableData object.
The problem seems to be silly but any one with any answers ....
Thank You All.
I suspect you are having a memory management issue. I could be mistaken on this, but I believe that even:
NSURLConnection* connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
won't work, because connection will be released at the end of the containing method, when connection goes out of scope. Make sure NSURLConnection *connection and NSMutableData *data are declared as member variables where ever you are doing this, and that you alloc and init them appropriately. My code usually looks like:
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:30.0];
// cancel any old connection
if(connection) {
[connection cancel];
[connection release];
}
// create new connection and begin loading data
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if(connection) {
// if the connection was created correctly, release old data (if any), and alloc new
[data release];
data = [[NSMutableData data] retain];
}
Also, release the connection and data in dealloc. For good measure, release and set them to nil at the very end of didFailWithError and didFinishLoading:
[connection release];
connection = nil;
[data release];
data = nil;
Good luck; I've done this a million times, let me know if you cannot get it working.
You don't happen to be calling the NSConnection in a thread do you? If you are then what's happening is that the thread is terminating before NSConnection and its delegates have finished so it'll just bomb out without an error.
A workaround for this is in this thread
You're not getting any error messages in didFailWithError either? Kind of a silly suggestion, but are you sure you're setting the proper NSURLConnection delegate?
NSURLConnection* connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
Sometimes it's something small like that.
Another idea is to drop in a toolkit like ASIHTTPRequest and see if it works going through them.
There also could be problems, if are trying to start NSURLConnection from another Thread.
Please call method [connection start] on main thread, if you have not customized Run Loop for it.