2015-07-03 1 views
1

Я начинаю внедрять метод загрузки с использованием NSURLSession и успешно загружать разные файлы из нескольких запросов. Но теперь я хотел добавить отслеживание прогресса, однако делегаты для загрузки не запускаются.NSURLSessionDownloadTask Делегаты, не вызывающие метод didWriteData

Вот мой код:

NSURLSessionConfiguration *defaultConfigObject = NSURLSessionConfiguration defaultSessionConfiguration]; 

NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate:self delegateQueue:nil]; 

NSURLSessionDownloadTask * downloadTask = [defaultSession downloadTaskWithRequest:request completionHandler:^(NSURL * __nullable location, 
                   NSURLResponse * __nullable response, NSError * __nullable error) { 

NSData *data = [NSData dataWithContentsOfURL:location]; 

[[NSFileManager defaultManager] createFileAtPath:docPath contents:data attributes:nil]; 

if ([[NSFileManager defaultManager] fileExistsAtPath:docPath]) { 

NSDictionary *notificationDic = [[NSDictionary alloc] initWithObjectsAndKeys:docPath,@"docPath", item, @"item", nil]; 

[[NSNotificationCenter defaultCenter] postNotificationName: @"openFile" object:nil userInfo:notificationDic]; 

} 

}]; 
[downloadTask resume]; 

У меня есть NSURLSessionDownloadDelegate на моем файле заголовка.

Мне нужно было использовать обработчик завершения для выполнения различных задач с файлом.

Есть ли способ, я могу это сделать?

+0

Не связанный с вопросом, но я бы посоветовал использовать 'createFileAtPath'. Одним из преимуществ «NSURLSessionDownloadTask» является то, что он передает загрузку непосредственно в постоянное хранилище, что дает вам преимущество в использовании данных dataWithContentsOfURL и 'createFileAtPath: contents:'. Вместо этого я мог бы предложить обходить загрузку в «NSData» и использовать метод 'NSFileManager'' moveItemAtURL', чтобы переместить его из 'location' в' [NSURL fileURLWithPath: docPath] '. – Rob

+0

@Rob сделаю. Спасибо. –

ответ

2

Если вы используете команду downloadTaskWithRequest без параметра completionHandler, тогда будут вызваны методы делегатов прогресса. Очевидно, что вам нужно будет переместить код в данный момент в блок completionHandler в метод didFinishDownloadingToURL. Но если вы это сделаете, вы увидите didWriteData.

+0

Я был просто обработчиком завершения, потому что мой «docPath» отличается от файла к файлу, и я могу одновременно загружать несколько файлов, поэтому мне было легче обрабатывать ответ. Но я попытаюсь использовать didFinishDownloadingToURL. Спасибо. –

+0

Да, это раздражает, но это то, что вам нужно будет сделать, чтобы наслаждаться обратным вызовом 'didWriteData'. Когда создается «NSURLSessionTask», ему присваивается «taskIdentifier», и вы можете создать словарь значений «docPath» назначения, используя ключ «taskIdentifier» в качестве ключа. Или, в качестве альтернативы, в 'didFinishDownloadingToURL' вы можете получить« originalRequest »и использовать некоторый параметр этого запроса (например,« URL ») в качестве ключа для вашего словаря. Это утомительно, но мы это делаем. Или вы можете использовать что-то вроде AFNetworking, которое заботится об этой головной боли для вас. – Rob

1

Вы должны начать загрузку с:

- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url; 

и реализовать метод делегата для вашего прогресса:

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask 
             didWriteData:(int64_t)bytesWritten 
            totalBytesWritten:(int64_t)totalBytesWritten 
          totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite; 

И поскольку вам необходимо выполнять различные задания, когда закончите, вы должны также Внесите этот делегат метод:

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask 
          didFinishDownloadingToURL:(NSURL *)location; 

По существу, обработчик завершения подпрограммы - это «удобные» подпрограммы, чтобы быстро выполнить задачу, а затем, когда закончите, выполните обработчик завершения. Но они не называют другие подпрограммы делегатов.

+0

Я просто использовал обработчик завершения, потому что мой «docPath» отличается от файла к файлу, и я могу одновременно загружать несколько файлов, поэтому мне было легче обрабатывать ответ. Но я попытаюсь использовать didFinishDownloadingToURL. Спасибо. –

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