AFNetworking Загрузка и сохранение данных только при успешном выполнении запроса

В моем приложении iOS я использую библиотеку AFNetworking для управления необходимыми операциями HTTP.

Я создал метод для загрузки файла:

+ (void)downloadFile:(File *)file progress:(void (^)(NSUInteger receivedBytes, long long totalReceivedBytes, long long totalExpectedBytes))progress success:(void (^)())success failure:(void (^)(NSError *error))failure
{
    NSURLRequest *request = [NSURLRequest requestWithURL:file.url];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:[FCFileManager pathForTemporaryDirectoryWithPath:file.key.lastPathComponent] append:NO];

    [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead)
    {
        progress(bytesRead, totalBytesExpectedToRead, totalBytesExpectedToRead);
    }];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        success();
    }

    failure:^(AFHTTPRequestOperation *operation, NSError *error)
    {
        failure(error);
    }];

    [operation start];
}

Хотя, есть проблема с этим методом. Если загрузка отменена (принудительный выход), файл все еще можно найти в каталоге приложения. Как создать загрузку файла, чтобы сохранить файл в каталог документов только после успешного завершения загрузки?


person Daumantas Versockas    schedule 04.02.2016    source источник
comment
возможно, в завершении блока вы можете поймать операцию.ошибка. если ноль, загрузка завершилась успешно.   -  person Quetool    schedule 04.02.2016


Ответы (2)


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

person Flexicoder    schedule 04.02.2016
comment
Это звучит как работа... Может быть, есть лучший способ справиться с операцией загрузки? - person Daumantas Versockas; 04.02.2016
comment
Единственный другой вариант - не записывать файл на диск во время загрузки, а хранить его в памяти. Это означает, что при загрузке больших файлов вы будете использовать всю память устройства. Предложение @flaxicode очень широко используется и считается хорошим решением. - person rckoenes; 04.02.2016

Используя NSUrlSession из платформы Foundation самостоятельно обработает неудачную загрузку:

- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData
                                   completionHandler:(void (^)(NSURL *location,
                                                               NSURLResponse *response,
                                                               NSError *error))completionHandler

Вы должны передавать нулевой обработчик завершения только при создании задач в сеансах, делегаты которых включают метод URLSession:downloadTask:didFinishDownloadingToURL:.

Ваше приложение может получить объект summaryData двумя способами:

  • Если ваше приложение отменяет существующую передачу путем вызова метода cancelByProductionResumeData:, объект сеанса передает объект возобновления данных обработчику завершения, указанному вами в этом вызове.

  • Если передача не удалась, объект сеанса предоставляет объект NSError либо своему делегату, либо обработчику завершения задачи. В этом объекте ключ NSURLSessionDownloadTaskResumeData в словаре userInfo содержит объект резюме.

После создания задачи ее необходимо запустить, вызвав ее метод возобновления.

Если запрос завершается успешно, параметр местоположения блока обработчика завершения содержит местоположение временного файла, а параметр ошибки равен нулю. Если запрос завершается ошибкой, параметр местоположения равен нулю, а параметр ошибки содержит информацию об ошибке.

Если вы хотите использовать для этого AFNetworking, он должен быть полностью совместим, поскольку у него есть AFURLSessionManager для обработки NSUrlSession.

person GoRoS    schedule 04.02.2016
comment
Вы говорите о загрузке в соответствии с примером: github.com/AFNetworking/AFNetworking? - person Daumantas Versockas; 04.02.2016
comment
Я говорю о загрузке файлов в целом, как я уже сказал, Apple уже обрабатывает то, что вам нужно, в своей структуре, не создавая временных файлов. Документация довольно ясно об этом. - person GoRoS; 04.02.2016