NSURLSessionDownloadTask — читать загруженные данные перед выполнением FinishDownloading

Я пытаюсь заменить NSURLConnection на NSURLSession, но обнаружил, что с NSURLSession я не могу читать промежуточные фрагменты данных, как в NSURLConnection с методом делегата.

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

Раньше я начинал использовать данные до завершения. Я как бы стримлю. Как я могу получить доступ к загруженным данным до завершения NSURLSession?

Я заметил, что есть (NSURL *)location, который является временным сохраненным местоположением данных из NSURLSession до завершения, но я могу получить этот URL-адрес до завершения?

Спасибо


Попробовал это, как предложил Роб:

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionTask *task = [session dataTaskWithRequest:request];
[task resume];

Однако вызывался только метод didRecieveResponse.

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler

но didReceiveData не вызывается.

Пробовал менять задачу на downloadTask

NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate:self delegateQueue: [NSOperationQueue mainQueue]];
NSURLSessionDownloadTask * downloadTask =[defaultSession downloadTaskWithRequest:request];
[downloadTask resume];

Он работает с делегатом загрузки, но делегат данных (didReceiveData) не вызывается.

Кто-нибудь может сказать мне, что я сделал неправильно?


person John    schedule 23.08.2014    source источник


Ответы (1)


Если вы используете представление NSURLSession на основе делегатов, протокол NSURLSessionDataDelegate включает метод didReceiveData, так что вы можете создать экземпляр NSURLSessionDataTask, а затем написать свой собственный код потоковой передачи, как если бы вы использовали NSURLConnection:

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self];
NSURLSessionTask *task = [session dataTaskWithRequest:request];
[task resume];

В качестве альтернативы, если вы не хотите писать свой собственный код потоковой передачи, но хотите, чтобы NSURLSession передавал его в файл для вас и информировал вас о его ходе, снова используйте представление NSURLSession на основе delegate, создайте и resume a NSURLSessionDownloadTask:

NSURLSessionTask *task = [session downloadTaskWithRequest:request];
[task resume];

Сделав это, вы можете затем реализовать метод didWriteData протокола NSURLSessionDownloadDelegate, и он будет информировать вас о записи данных (очевидно, пока ваше приложение находится на переднем плане; если вы используете фоновый сеанс, а приложение не активно, ваш приложение повторно активируется только после завершения всех фоновых задач). Но таким образом вы получаете лучшее из обоих миров, где NSURLSession выполняет потоковую загрузку, но будет держать вас в курсе ее хода.

Но если вы используете NSURLSessionDownloadTask, у вас не будет доступа к NSURL временного файла, пока загрузка не будет завершена (а в didFinishDownloadingToURL вы переместите этот временный файл в его постоянное конечное местоположение).

person Rob    schedule 23.08.2014
comment
Спасибо, Роб, за быстрый ответ. Звучит очень хорошо, я не знал, что могу использовать dataTask для загрузки файла. Позвольте мне попробовать использовать метод делегата didReceiveData и вернуться к вам. Большое спасибо - person John; 23.08.2014
comment
Привет, Роб, я пытался и пытался, но не смог заставить его работать. Не могли бы вы взглянуть на мой РЕДАКТИРОВАТЬ и посмотреть, не сделал ли я что-то не так. Спасибо. - person John; 01.09.2014
comment
@user1256663 user1256663 А вы назвали тот блок completionHandler, который вам предоставил didReceiveResponse? Я знаю, что в первый раз, когда я использовал NSURLSession на основе делегата, я полностью упустил из виду этот критический параметр: он не будет продолжаться, пока вы не вызовете этот блок завершения. Каждый раз, когда любой из этих методов делегата предоставляет блок завершения (полученный ответ, полученный вызов, обработка перенаправления), вы должны вызвать его. - person Rob; 01.09.2014
comment
Вот оно! Спасибо, Роб. Я так долго дергал себя за волосы. - person John; 01.09.2014
comment
Спасибо, Роб, еще раз. Я просто искал ту же тему, и все, что вы написали, верно. К сожалению, dataTask не может быть запущен в фоновом режиме (downloadTask может) ... так что любой, кто читает это, остерегайтесь этого :) - person animal_chin; 12.05.2015