【问题标题】:How to upload task in background using afnetworking如何使用afnetworking在后台上传任务
【发布时间】:2014-11-26 16:18:15
【问题描述】:

我正在尝试使用 AFNetworking 上传大文件,并在应用程序处于后台时继续上传。

我可以很好地上传文件,但是当我尝试使用后台配置时——应用程序崩溃并出现以下堆栈跟踪: 例外:EXC_BAD_ACCESS(代码=1,地址=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);
    }
}];

【问题讨论】:

  • 嘿,你找到解决办法了吗?我面临同样的问题。请帮助我。

标签: ios iphone file-upload afnetworking-2 nsurlsessionconfiguration


【解决方案1】:

我正在回答我自己的问题,希望它能帮助一些人。

我在任何地方都找不到此文档,但看起来您在使用后台会话配置时必须使用 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];

【讨论】:

  • 我也有你上面提到的同样的问题。就我而言,我需要在单个请求中上传多个文件。这种方式可以将多个文件附加到单个请求吗?
  • 你能分享一下 OMGMultipartFormData 文件吗?我试图找到它,但没有找到。
  • 这个答案很不清楚。 uploadBundle 是什么?你想用id path 线做什么?
  • 什么是 OMGMultipartFormData
  • 请解释“OMGMultipartFormData”。
【解决方案2】:

问题似乎是您正在尝试使用“流式请求”而不是文件。该代码适用于

NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:[NSURL fileURLWithPath:filePath] progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error){

.... }];

方法没有任何问题。我还发现,如果您尝试使用文件数据而不是实际文件(使用 uploadTaskWithRequest:fromData:progress:completionHandler:),则上传失败,如Upload tasks from NSData are not supported in background sessions中所述

【讨论】:

  • 所以一次只能上传一个文件?没有等效的 multipartFormData?
  • 您可以上传分段数据,只需将分段数据保存到文件中,然后上传文件即可。然后,[serializer requestWithMultipartFormRequest:request writingStreamContentsToFile:filePathtemp completionHandler:^(NSError *error) { NSURLSessionUploadTask *uploadTask = [self.activeSessionManager uploadTaskWithRequest:request fromFile:filePathtemp progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error ) { }]; [上传任务恢复]; }];
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多