NSURLSession和后台流上传

时间:2013-11-14 10:02:14

标签: ios background alassetslibrary uploading nsurlsession

使用NSURLSession将照片从资源库上传到服务器时,我遇到了一些问题。

首先NSURLSession不支持流式上传。我试图使用它时遇到异常:

@property (nonatomic, strong) NSURLSession *uploadSession;

...

_uploadSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration
                backgroundSessionConfiguration:kUploadBackgroundURLSessionIdentifier] delegate:self delegateQueue:nil];

...

NSURLSessionUploadTask *task = [self.uploadSession uploadTaskWithStreamedRequest:URLRequest];

这是一个例外:

Terminating app due to uncaught exception 'NSGenericException', reason: 'Upload tasks in background sessions must be from a file'

这真的很奇怪,因为Apple的手册中不包含任何有关仅使用uploadTaskWithRequest:fromFile:进行后台会话的信息。如果我想从资源库上传真正庞大的视频文件怎么办?我应该先将它保存到我的tmp目录吗?

看起来唯一的理由是使用uploadTaskWithRequest:fromFile:,对吧?但是我有一个问题,如果上传过程中断并开始在后台上传下一部分,服务器如何知道该文件的哪一部分正在上传?

我应该为此管理一些事情吗?以前我在URL请求中使用了Content-Range,如果我想继续上传之前启动的文件的一部分。现在我不能这样做 - 我必须在创建上传任务之前创建一个URL请求,看起来NSURLSession必须自动为我做这样的事情?

有人做过这样的事吗?感谢

4 个答案:

答案 0 :(得分:1)

转换为NSData并在app文件夹中复制和写入

ALAsset *asset = [cameraRollUploadImages objectAtIndex:startCount];
ALAssetRepresentation *representation = [asset defaultRepresentation];

// create a buffer to hold the data for the asset's image
uint8_t *buffer = (Byte *)malloc(representation.size);// copy the data from the asset into the buffer
NSUInteger length = [representation getBytes:buffer 
                                  fromOffset:0 
                                      length:representation.size 
                                       error:nil];

// convert the buffer into a NSData object, free the buffer after
NSData *image = [[NSData alloc] initWithBytesNoCopy:buffer 
                                             length:representation.size
                                       freeWhenDone:YES];

答案 1 :(得分:0)

目前,除了将图片保存到本地文件系统或临时目录之外,没办法。

以下代码确保您的数据不会因exif标记而丢失。 (ALAsset => NSData)

ALAssetRepresentation *assetRepresentation = [(ALAsset *)assetBeingUploaded defaultRepresentation];
uint8_t *buffer = (uint8_t *)malloc(sizeof(uint8_t)*[assetRepresentation size]);
NSUInteger buffered = 0;
if (buffer != NULL)
buffered = [assetRepresentation getBytes:buffer fromOffset:0.0 length:assetRepresentation.size error:nil];
self.imageBeingUploaded = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];

后台会话中的上传任务不支持完成处理程序。我们应该去。,

- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;  

我怀疑如果我们使用后台会话&amp ;;我们如何得到响应标题或正文。使用文件请求uploadtask?

答案 2 :(得分:0)

一个干净的解决方法是创建一个NSOperation,它将使用NSStream将文件从资产库复制到临时文件夹,这样就不会在文件很大的情况下发生崩溃,当操作完成时你会安排一个上传该临时文件,上传完成后将其删除。

在我的情况下,我需要以多部分格式发送文件,因此需要创建临时文件,但我在上传大文件时遇到问题,超过2 Gb,示例电影超过20分钟。

答案 3 :(得分:0)

您无法在后台上传NSData,需要上传文件格式。您可以按目录路径

创建它
相关问题