9

我在使用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

4 回答 4

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];
于 2013-11-15T18:39:24.147 回答
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;  

我怀疑如果我们使用后台会话和上传任务以及使用文件的请求,我们如何获取响应标头或正文?

于 2014-01-27T11:21:23.937 回答
0

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

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

于 2014-11-27T08:21:52.053 回答
0

你不能在后台上传 NSData 你需要上传文件格式。您可以通过目录路径创建它

于 2015-05-13T13:05:27.053 回答