0

I have a question about NSURLConnection: I want download an image with:

NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];

the first delegate called (correctly) is

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

after this is called one time:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

and immediately:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

up to here everything is correct, but after connectionDidFinishLoading is fired once again the didReceiveData delegate for the same connection, I identify connection by:

NSString * connectionKey = [[[connection originalRequest] URL] absoluteString];

Is this possible?

update, more infos:

My app fire many simultaneous connections and I store infos for any connection in a dictionary, when a delegate was called I retrive connection info using the key: NSString * connectionKey = [[[connection originalRequest] URL] absoluteString]; for 99% of connections everything is all right but for one (avery time the same!) connection I have this behavior


here the complete implementation:

    - (void)downloadFileFromUrl:(NSURL *)url
                     inPath:(NSString *)completeFilePath
          dataReceivedBlock:(void (^)(long long byteDownloaded ,long long totalByte))dataReceivedBlock
                   endBlock:(void (^)(NSString * downloadPath, NSDictionary * responseHeaders))endBlock
                  failBlock:(void (^)(NSString * downloadPath, NSDictionary * responseHeaders, NSError * error))failBlock
{
    //save the connection infos       
NSMutableDictionary * requestData = [[NSMutableDictionary alloc] init];
if(dataReceivedBlock)
[requestData setObject:[dataReceivedBlock copy] forKey:@"dataReceivedBlock"];
if(endBlock)
[requestData setObject:[endBlock copy] forKey:@"endBlock"];
if(failBlock)
[requestData setObject:[failBlock copy] forKey:@"failBlock"];

        [requestData setObject:[NSNumber numberWithBool:YES] forKey:@"usingBlock"];
        [requestData setObject: completeFilePath forKey:@"downloadDestinationPath"];

    //delete the file if already on fs
    if([[NSFileManager defaultManager] fileExistsAtPath: completeFilePath])
        [[NSFileManager defaultManager] removeItemAtPath:completeFilePath error:nil];

    // Create the request.
    NSURLRequest * urlRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLCacheStorageAllowed timeoutInterval:TIME_OUT];
    NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
    if (!theConnection)
    {
        // Inform the user that the connection failed.
        failBlock(completeFilePath,nil,[NSError errorWithDomain:@"Connection fail" code:0 userInfo:nil]);
    }

    //add connection infos to the requests dictionary
    NSString * connectionKey = [[[theConnection originalRequest] URL] absoluteString];
    [self.requests setObject:requestData forKey:connectionKey];
}

here a delegate example:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

NSString * connectionKey = [[[connection originalRequest] URL] absoluteString];
NSMutableDictionary * requestData = [self.requests objectForKey:connectionKey];
NSFileHandle *file = [requestData objectForKey:@"fileHandle"];
[file closeFile];

//se la richiesta usa o no block
BOOL usingBlock = [[requestData objectForKey:@"usingBlock"] boolValue];
if(usingBlock)
{
    __block void (^endBlock)(NSString * , NSDictionary *) = [requestData objectForKey:@"endBlock"];
    if(endBlock)
        endBlock([requestData objectForKey:@"downloadDestinationPath"],[requestData objectForKey:@"responseHeaders"]);
}
else
    [self.delegate downloadEnded:[requestData objectForKey:@"responseHeaders"]];


//elimino dati richiesta
[self.requests removeObjectForKey:[NSString stringWithFormat:@"%@",connectionKey]];

//Inibisco standby
[UIApplication sharedApplication].idleTimerDisabled = NO;
}
Kappe
  • 9,217
  • 2
  • 29
  • 41
  • What is that mean?? You are saying didReceiveData method called even after your connectionDidFinishLoading: method?? – Dinesh Raja Feb 21 '13 at 10:51
  • YES! My app fire many simultaneous connections and I store infos for any connection in a dictionary, when a delegate was called I retrive connection info using the key: NSString * connectionKey = [[[connection originalRequest] URL] absoluteString]; for 99% of connections everything is all right but for one (avery time the same!) connection I have this behavior – Kappe Feb 21 '13 at 10:56
  • Show your code how you are creating connections and intialize it.. And one thing is to be clear.. That it won't call as you said in any situation.. It would be a problem in somewhere else.. You may call it manually in any places. Post your whole code for NSUrlConnection Delegate and initializing methods – Dinesh Raja Feb 21 '13 at 10:59
  • Where are you initializing the connection? – apascual Feb 21 '13 at 11:02
  • I never called manually any delegate, the point is: the connection didReceiveData: was called after connectionDidFinishLoading (when I delete the connection infos from the self.requests dictionary) and then in didReceiveData: i cant retrive the correct NSMutableDictionary * requestData – Kappe Feb 21 '13 at 11:30

2 Answers2

0

It's impossible. It's must be different connection callback.

ensure each connection use unique delegate, or unique switch branch in the same delegate.

Wubao Li
  • 1,728
  • 10
  • 13
  • @Kappe you can test the single problem connection URL. Basically, a connection is closed when you receive delegate method didfinishloading – Wubao Li Feb 24 '13 at 16:35
0

Obviously the solution is really simple -_- The error is in the connection key identifier:

NSString * connectionKey = [[[connection originalRequest] URL] absoluteString];

my assumption is that key are unique, but if I make x parallel downloadS for the same file at the same url the assumption is wrong ;)

Kappe
  • 9,217
  • 2
  • 29
  • 41