5

I am using an NSURLConnection in an NSThread but none of the NSURLConnection's delegate methods are executed! I have a main method in my NSTread subclass and a while loop that keeps the thread active. Any help?

Sorry for all of this code but I think its the best way to describe my problem. So this is an object that does the async connection calling createConnectionWithPath:userObjectReference

@interface WSDAsyncURLConnection : NSObject 
{
    NSMutableData *receivedData;
    NSDate *connectionTime;
    NSURLConnection *connection;

    id _theUserObject;

}


@property (nonatomic, retain) NSMutableData *receivedData;
@property (nonatomic, retain) NSDate *connectionTime;
@property (nonatomic, assign) NSURLConnection *connection;

- (void)createConnectionWithPath:(NSString *)thePath userObjectReference:(id)userObject;


@end


#import "WSDAsyncURLConnection.h"

@implementation WSDAsyncURLConnection
@synthesize connectionTime, receivedData, connection;


- (void) terminate
{
    if (self.connection) {
        [self.connection release];
        self.connection = nil;
    }
}   


- (void) createConnectionWithPath:(NSString *)thePath userObjectReference:(id)userObject;
{   
    _theUserObject = userObject;


    NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:thePath]
                                                cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:60];


    self.connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];

    if (self.connection) 
    {
        /* record the start time of the connection */
        self.connectionTime = [NSDate date];

        /* create an object to hold the received data */
        self.receivedData = [NSMutableData data];
    } 
}


- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [self.receivedData setLength:0];   
}

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    /* appends the new data to the received data */ 
    [self.receivedData appendData:data];
}

- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{    
    [self terminate];
}


- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
    // displays the elapsed time in milliseconds
    NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:self.connectionTime];
    // displayes the length of data received
    NSUInteger length = [self.receivedData length];

    NSString* aStr = [[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding];   

    [self terminate];


    [[NSNotificationCenter defaultCenter] postNotificationName:WSDAsynchURLConnectionDidFinished
                                                        object:_theUserObject 
                                                      userInfo:[NSDictionary dictionaryWithObject:aStr forKey:@"urlResponseString"]];

    NSLog(@"ti=%f, l=%d, response=%@", elapsedTime, length, aStr);

}

@end

This code is mostly from an apple's example project and it works fine outside an NSThread. But when I use it in the following thread subclass no delegate method is executed !!

@implementation IncomingThread



- (void) main {

    NSAutoreleasePool *poool = [[NSAutoreleasePool alloc] init];


// I start the URLConnection here ... But no delegate is executed !
        [urlConn createConnectionWithPath:@"http://localhost:8888" userObjectReference:nil];


    while (![self isCancelled]) {

        [NSThread sleepForTimeInterval:3.];
    }


    [poool release];

}


- (id) init
{
    self = [super init];
    if (self != nil) {

        urlConn = [[WSDAsyncURLConnection alloc] init];
    }
    return self;
}


- (void) dealloc {

    NSLog(@"deallocating (%@)...", [self className]);


    [urlConn release];

    [super dealloc];
}
Vassilis
  • 2,878
  • 1
  • 28
  • 43

4 Answers4

3

First of all: you don't need to use NSURLConnection in the separate thread. Since it is asynchronous it doesn't block the main thread. Second: there is not processing of your connection because you always stop the execution of the thread's runloop with this peace of code:

 while (![self isCancelled]) {
        [NSThread sleepForTimeInterval:3.];
    }

From the docs for the sleepForTimeInterval:

No run loop processing occurs while the thread is blocked.
Max
  • 16,679
  • 4
  • 44
  • 57
  • xmmm... Even if I comment `sleepForTimeInterval` still no delegates call occur. (I don't release the thread - except if it is released on its own when `main` method finishes but no!) – Vassilis Feb 22 '11 at 18:53
  • Yep, of course, cause the thread exits immediately. If you want to use separate thread then use synchronous request or do async one in the main thread. – Max Feb 22 '11 at 18:55
  • "use synchronous request or do async one in the main thread" logical And solved my issue. Both ways worked Fine. (Async request on a thread is indeed !! noisy !!). Thank you very much. – Vassilis Feb 22 '11 at 19:03
1

You’re doing this the hard way. NSURLConnection does not play very nice with threads, since it needs a run loop to work. Your thread does not have a run loop and therefore the code does not work. Why not run the connection on the main thread? Or you can wrap the connection in an NSOperation, sample code here. And nowadays you also have the option to use a synchronous connection and dispatch it to a global GCD queue.

zoul
  • 102,279
  • 44
  • 260
  • 354
0

Did you remember to assign the delegate?

Something like:

self.connection.delegate = self;

Just because your class WSDAsyncURLConnection implements the delegate methods, doesn't mean they are being called.

Friesgaard
  • 2,975
  • 2
  • 17
  • 13
  • But of course -> `self.connection = [[NSURLConnection alloc] initWithRequest:theRequest **delegate:self** startImmediately:YES];` in the code above. Thank you anyway. – Vassilis Feb 22 '11 at 19:08
0

Late but it may save others life :)

Solution link is : NSURLConnection delege methods does not work

Önder
  • 61
  • 1
  • 1