2013-07-14 2 views
0

Мое приложение загружает файл из Интернета с помощью NSURLConnection.Загрузить с NSURLConnection возвращает пустые данные?

две проблемы происходят:

1) [соединение didReceiveData] никогда не называют

2) Когда [соединение didFinishDownloading] называется, мой self.currentData пуст

Что я делаю неправильно?

Мой заголовок выглядит следующим образом:

@interface DIFileDownloader : NSObject <NSURLConnectionDelegate> { 

    NSMutableData *currentData; 

} 

@property (nonatomic, assign) id <DIFileDownloaderDelegate> delegate; 

@property (nonatomic, retain) NSMutableArray *supportedFormats; 

@property (nonatomic, retain) NSMutableData *currentData; 

@property (nonatomic, retain) NSURLConnection *downloadAgent; 

@property (nonatomic) long long expectedContentSize; 

@property (nonatomic) float currentDownloadProgress; 

@property (nonatomic, getter = isRunning) BOOL running; 

-(instancetype)initWithSupportedFormats:(NSArray *)extensions; 

-(void)downloadFileAtURL:(NSURL *)url; 

-(NSString *)documentsDirectoryPath; 

@end 

И мой файл реализации:

-(instancetype)initWithSupportedFormats:(NSArray *)extensions { 

    self.supportedFormats = [[NSMutableArray alloc] initWithArray:extensions]; 

    self.running = NO; 
} 

-(void)downloadFileAtURL:(NSURL *)url { 

    NSString *fileExtension = [url pathExtension]; 

    if ([self.supportedFormats containsObject:fileExtension]) { 

     self.downloadAgent = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:url] delegate:self]; 

     [self.downloadAgent start]; 

     NSLog(@"Beginning download at URL:%@", url.absoluteString); 

    } 
    else { 

    } 

} 

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

    NSLog(@"Connection recieved response with size: %f", (float)[response expectedContentLength]); 

    self.expectedContentSize = (float)[response expectedContentLength]; 

    self.running = YES; 

    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; 

    NSLog(@"%i", [httpResponse statusCode]); 

    /* 

    if ([httpResponse statusCode] >= 200 && [httpResponse statusCode] <= 299) { 

    } 

    */ 

} 

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

    NSLog(@"%f", (float)[data length]); 

    [currentData appendData:data]; 

    self.currentDownloadProgress = ((float)[data length]/self.currentDownloadProgress); 

    NSLog(@"Connection recieved data. New progress is: %f", self.currentDownloadProgress); 

    if ([self.delegate respondsToSelector:@selector(downloader:progressChanged:)]) { 
     [self.delegate downloader:self progressChanged:self.currentDownloadProgress]; 
    } 

} 

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 

    NSLog(@"Connection failed"); 

    if ([self.delegate respondsToSelector:@selector(downloader:failedToDownloadFileAtURL:reason:)]) { 
     [self.delegate downloader:self failedToDownloadFileAtURL:connection.originalRequest.URL reason:error]; 
    } 

} 

-(void)connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL { 

    NSLog(@"Connection finished downloading with size: %f", (float)[currentData length]); 

    self.running = NO; 

    NSString *filename = [destinationURL.absoluteString lastPathComponent]; 

    NSString *docPath = [self documentsDirectoryPath]; 

    NSString *pathToDownloadTo = [NSString stringWithFormat:@"%@/%@", docPath, filename]; 

    NSError *error = nil; 

    [currentData writeToFile:pathToDownloadTo options:NSDataWritingAtomic error:&error]; 

    if (error != nil) { 

     NSLog(@"DIFileDownloader: Failed to save the file because: %@", [error description]); 

     if ([self.delegate respondsToSelector:@selector(downloader:failedToDownloadFileAtURL:reason:)]) { 
      [self.delegate downloader:self failedToDownloadFileAtURL:connection.originalRequest.URL reason:error]; 
     } 

} 
    else { 

     if ([self.delegate respondsToSelector:@selector(downloader:finishedDownloadingFileNamed:atPath:)]) { 
      [self.delegate downloader:self finishedDownloadingFileNamed:filename atPath:pathToDownloadTo]; 
     } 

    } 

} 

- (NSString *)documentsDirectoryPath { 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectoryPath = [paths objectAtIndex:0]; 
    return documentsDirectoryPath; 
} 

@end 
+1

Ну, с одной стороны, вы никогда не создаете свой объект 'NSMutableData'. –

+1

И, похоже, у вас такая же проблема, как и [NSURLConnection connection: didReceiveData: не вызывается на ios5] (http://stackoverflow.com/questions/13085007/nsurlconnection-connectiondidreceivedata-is-not-called-on-ios5) Также есть еще один полезный ответ в [NSURLConnection didReceiveData: не получил вызов iOS] (http://stackoverflow.com/q/14553538) –

+0

В вашем коде есть ряд ошибок: ваш метод init не соответствует правилам , и не возвращает объект. То, как вы вычисляете 'currentDownloadProgress', не работает, и еще несколько. Я бы предложил добавить в свой код довольно много утверждений и ошибок, а затем начать сеансы отладки. – CouchDeveloper

ответ

0

Как уже упоминалось в других и в моем комментарии, есть несколько ошибок в коде, которые нужно исправить.

Но есть и один большое заблуждение - вытекающее из бывшей ужасной документации NSURLConnection:

connectionDidFinishDownloading:destinationURL: НЕ метод делегата от двух делегатов NSURLConnection, а именно, NSURLConnectionDelegate и NSURLConnectionDataDelegate, которые вы должны реализовать в вашем дело.

Минимальный набор методов делегата необходимо реализовать следующие:

Для NSURLConnectionDelegate:

  • (аннулируются) соединение: (NSURLConnection *) подключение didFailWithError: (NSError *) ошибка;

то для NSURLConnectionDataDelegate:

  • (пустоты) соединение: (NSURLConnection *) соединение didReceiveResponse: ответ (NSURLResponse *);

  • (void) подключение: (NSURLConnection *) подключение сделалReceiveData: (NSData *) данные;

  • (пусто) подключениеDidFinishLoading: (NSURLConnection *) соединение;

Если вы не возражаете, я положил образец минимальной реализации на Gist: SimpleGetHTTPRequest, который должен дать вам толчок сделать реализовать свой собственный класс запроса HTTP.

+0

Спасибо за этот образец, я думаю, у меня есть то, что мне нужно! – JohnWickham

 Смежные вопросы

  • Нет связанных вопросов^_^