Как загрузить задание в фоновом режиме, используя afnetworking
Я пытаюсь загрузить большие файлы с помощью AFNetworking и продолжить загрузку, когда приложение находится в фоновом режиме.
Я могу загружать файлы просто отлично, но когда я пытаюсь использовать фоновую конфигурацию - приложение вылетает со следующей трассировкой стека: Исключение: EXC_BAD_ACCESS (code=1, address=0x8000001f))
_CFStreamSetDispatchQueue
-[__NSCFBackgroundDataTask captureStream:]
__70-[__NSCFBackgroundDataTask _onqueue_needNewBodyStream:withCompletion:]_block_invoke_2
_dispatch_call_block_and_release
_dispatch_queue_drain
_dispatch_queue_invoke
_dispatch_root_queue_drain
_dispatch_worker_thread3
_pthread_wqthread
Вот пример кода:
Примечание: когда я использую [NSURLSessionConfiguration defaultSessionConfiguration]
загрузка прошла успешно, но не будет продолжена, когда приложение находится в фоновом режиме. [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.company.appname.uploadservice"]
вызывает сбой приложения.
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[uploadBundle.uploadUrl absoluteString] parameters:[uploadBundle getParameters] constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:uploadBundle.fileDataUrl name:uploadBundle.fileName fileName:uploadBundle.fileName mimeType:uploadBundle.mimeType error:nil];
} error:nil];
Authentication *authentication = [Authentication getInstance];
[request addValue:authentication.token forHTTPHeaderField:@"token"];
[request addValue:authentication.authorization forHTTPHeaderField:@"Authorization"];
//NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.company.appname.uploadservice"];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSProgress *progress = nil;
_currentUploadTask = [manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
} else {
NSLog(@"%@ %@", response, responseObject);
}
}];
2 ответа
Я отвечаю на свой вопрос в надежде, что это поможет нескольким людям.
Я не могу найти это нигде, но похоже, что вы должны использовать uploadTaskWithRequest:fromFile:progress:completionHandler:
при использовании фоновой конфигурации сеанса.
Вот простой пример:
AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
id config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.opentext.core.uploadservice"];
id session = [NSURLSession sessionWithConfiguration:config delegate:appDelegate delegateQueue:[NSOperationQueue new]];
OMGMultipartFormData *multipartFormData = [OMGMultipartFormData new];
//[multipartFormData addFile:data parameterName:@"file" filename:nil contentType:nil];
[multipartFormData addParameters:[uploadBundle getParameters]];
NSURLRequest *rq = [OMGHTTPURLRQ POST:[uploadBundle.uploadUrl absoluteString] :multipartFormData];
id path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"upload.NSData"];
[rq.HTTPBody writeToFile:path atomically:YES];
[[session uploadTaskWithRequest:rq fromFile:[NSURL fileURLWithPath:path]] resume];
Похоже, проблема в том, что вы пытаетесь использовать потоковый запрос вместо файла. Код работает с
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest: запрос из файла:[NSURL fileURLWithPath:filePath] progress:&progress completeHandler:^(NSURLResponse * ответ, идентификатор responseObject, ошибка NSError *) {
....}];
Метод без проблем. Я также обнаружил, что если вы попытаетесь использовать данные файла вместо реального файла (с uploadTaskWithRequest: fromData: progress: завершением Handler:), загрузка завершится неудачно, как описано в разделе Задачи загрузки из NSData, не поддерживаются в фоновых сеансах.