views:

285

answers:

2

I want to create a class to handle all the HTTP connection work for other classes(in order to avoid writing codes repeatedly). I call it ConnectionCenter(subclass of NSObject) and add the following codes to it:

-(void)connect:(NSString *)strURL obj:(ConnectCenter *)objConnect
{
    NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:strURL]
                cachePolicy:NSURLRequestUseProtocolCachePolicy
               timeoutInterval:60.0];

    NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:objConnect];
    if (theConnection) 
    {
     // receivedData is declared as a method instance elsewhere
     receivedData = [[NSMutableData data] retain];
    } 
    else 
    { 
     // inform the user that the download could not be made
    }

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // append the new data to the receivedData
    // receivedData is declared as a method instance elsewhere
    [receivedData appendData:data];
}

And other classes call it by passing a URL and an object of ConnectionCenter. But the method 'didReceiveData' in ConnectionCenter is not called. Any ideas about what's the problem with it?

+2  A: 

You'll need to call [theConnection setDelegate:self] after you setup the connection, since connection:didReceiveData: is a delegate method.

Read the documentation for more info.

Rich Catalano
A: 

A couple of things about this code...

First, it's confusing which object you're actually setting as the delegate. The call to connection:didReceiveData: is going to be called on the connection's delegate, which is whatever object you passed into your connect:obj: method. It seems odd that you've got an instance method on ConnectionCenter that can start up a connection with a different ConnectionCenter object as the delegate. Make sure you're looking at the connection:didReceiveData: method on the right object.

If you're not receiving any data, it's possible that your connection either failed to connect or simply completed without returning any data. You should implement the connectionDidFinishLoading: and connection:didFailWithError: delegate methods so you'll know if the connection has finished, with or without returning data.

Finally, you've got a race condition that'll bite you if you get a good, fast connection. The NSURLConnection object will start running as soon as you create it. If there's any data to read it'll call connection:didReceiveData: and you'll append it to receivedData. But if the connection's fast enough you might end up trying to append data to a receivedData that hasn't been created yet. It's a small chance but even though NSURLConnection's init method doesn't block, it's unwise to make any assumptions about how much work it does to get the connection going before returning. Create receivedData before starting the connection so that you can be sure of having a place to put the data when it comes in.

Tom Harrington
Thanks indeed. I change the delegate to 'self' and it works. Maybe there was a connection error last time.
iPhoney