Comment download une tâche en arrière-plan en utilisant afnetworking

J'essaie de download de gros files en utilisant AFNetworking et de continuer le téléchargement lorsque l'application est en arrière-plan.

Je peux download des files très bien, mais quand je tente d'utiliser une configuration en arrière-plan – l'application se bloque avec la stacktrace suivante: Exception: EXC_BAD_ACCESS (code = 1, adresse = 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 

Voici un exemple de code:

Remarque: Lorsque j'utilise [NSURLSessionConfiguration defaultSessionConfiguration] le téléchargement réussit mais ne se poursuit pas lorsque l'application est en arrière-plan. [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.company.appname.uploadservice"] provoque le blocage de l'application.

 NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLSsortingng:[uploadBundle.uploadUrl absoluteSsortingng] 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); } }]; 

Je réponds à ma propre question dans l'espoir que cela aidera quelques personnes.

Je ne peux pas find cela documenté nulle part, mais il semble que vous uploadTaskWithRequest:fromFile:progress:completionHandler: utiliser uploadTaskWithRequest:fromFile:progress:completionHandler: lors de l'utilisation d'une configuration de session en arrière-plan.

Voici un exemple simple:

 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 absoluteSsortingng] :multipartFormData]; id path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] ssortingngByAppendingPathComponent:@"upload.NSData"]; [rq.HTTPBody writeToFile:path atomically:YES]; [[session uploadTaskWithRequest:rq fromFile:[NSURL fileURLWithPath:path]] resume]; 

Les problèmes semblent être que vous essayez d'utiliser une "requête streamée" au lieu d'un file. Le code fonctionne avec

NSURLSessionUploadTask * uploadTask = [gestionnaire uploadTaskWithRequest: request fromFile: [NSURL fileURLWithPath: filePath] progression: & progression completionHandler: ^ (réponse NSURLResponse *, id réponseObjet, erreur NSError *) {

….}];

méthode sans problèmes. J'ai également constaté que si vous essayez d'utiliser datatables de file au lieu du file réel (avec uploadTaskWithRequest: fromData: progress: completionHandler :), le téléchargement échoue comme expliqué dans Charger des tâches de NSData ne sont pas pris en charge dans les sessions en arrière-plan