ios8:如何使用 NSURLSession 在后台上传 100 张照片?可用空间问题

Posted

技术标签:

【中文标题】ios8:如何使用 NSURLSession 在后台上传 100 张照片?可用空间问题【英文标题】:ios8: How do you upload 100s of photos in background using NSURLSession? Free space issue 【发布时间】:2015-03-20 06:48:00 【问题描述】:

照片应用如何在后台从 CameraRoll 上传所有内容?

我需要根据日期范围在后台上传 100 张照片。我的应用程序当前正在使用NSURLSession 和以下代码(我认为......)但为了使其工作,我的任务计划程序必须在应用程序运行之前将 JPG 复制到应用程序存储中的文件(请参阅:Background Upload With Stream Request Using NSUrlSession in ios8)进入背景。对于 100 多张照片,这需要太多时间和存储空间。

有没有办法使用“流”方法,或者从后台可靠地安排额外的NSURLSession 任务?我的开发人员说,可能在 iCloud 中的 CameraRoll 照片会导致后台调度失败。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didSendBodyData:(int64_t)bytesSent
totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend 
NSString *identifier = task.originalRequest.allHTTPHeaderFields[@"X-Image-Identifier"];

NSDictionary *d = [self sessionInfosDictionary];
NSURLSessionTaskInfo *info = d[identifier];
double p = (double)totalBytesSent/(double)totalBytesExpectedToSend;
info.progress = p;
[self saveSessionInfos:d];

for (id<PhotosUploaderDelegate>delegate in _delegates) 
    if ([delegate respondsToSelector:@selector(photoUploader:didUploadDataForAssetWithIdentifier:totalBytesSent:totalBytesExpectedToSend:)]) 
        [delegate photoUploader:self didUploadDataForAssetWithIdentifier:identifier totalBytesSent:totalBytesSent totalBytesExpectedToSend:totalBytesExpectedToSend];
    
  

【问题讨论】:

【参考方案1】:

任务不简单,还有很多工作要做。

从 [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:] 和 +[NSURLSession uploadTaskWith...] 方法开始。

您会看到棘手的部分是从上传错误中恢复。您需要通过检查 -[NSURLSession getTasksWithCompletionHandler:] 来跟踪应用程序中的每个后台上传。但首先要从头开始,后台会话配置和上传任务。

【讨论】:

我已经这样做了。问题(我认为)是 NSURLSession 需要处理我的应用程序存储中的文件,我认为将整个 CameraRoll 复制到我的 AppStorage 中没有意义。另外,我认为文件复制需要在我的应用程序处于“前台”时进行。我需要一种方法来给 NSURLSession 一个文件,而我的应用程序是“背景” 是的,每个后台上传都需要一个文件:您确实需要复制整个相机胶卷。而且......如果应用程序需要在前台复制每个图像......那么你有麻烦了,我同意......我现在看不到任何答案。【参考方案2】:

我还没有尝试过,但也许你可以复制文件并在后台会话回调中启动新的上传任务?这样您就可以一次复制和上传一个文件。

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler 
   // copy file and schedule new upload task

【讨论】:

我问过我的开发人员,他说如果照片在设备上是本地的,那可能是可能的。但他也表示,iOS8 照片框架现在包括访问 iCloud 上的照片,并且 API 不允许您进行区分。因此,如果照片不在本地,后台进程将在从 iCloud 获取照片之前超时。 如果不需要上传 iCloud 照片,我认为您应该能够使用 PHImageRequestOptions networkAccessAllowed = false 仅过滤本地图像。 另一方面,如果您还想上传 iCloud 照片,您可能会使用 PHCachingImageManager。如果您预先缓存所有图像,它们应该在后台异步下载(我假设在应用程序运行时)。最终,您应该在本地设备上拥有所有 iCloud 照片,然后您可以借助前面评论中的技术上传它们,但这充其量是不完整的 :) 我可以尝试一下,但要明确的是,如果设备存储空间不足,PHCachingImageManager 方法会起作用吗?这听起来不像是“流媒体”解决方案 我不确定,我猜如果需要存储空间,缓存的图像将被清除。如果你真的需要 100% 的图片上传,我不确定这是不是正确的方法,太多的移动部件和太多的未知数。如果你有时间,看看它是否可行会很有趣:)

以上是关于ios8:如何使用 NSURLSession 在后台上传 100 张照片?可用空间问题的主要内容,如果未能解决你的问题,请参考以下文章

iOS8:NSURLSession:NSURLSessionDataTask '客户端在收到整个响应之前关闭连接'

应用重启后监控 NSURLSession

NSURLSession 的 IOS9 SSL 错误

NSURLSession 错误域 = NSPOSIXErrorDomain 代码 = 2 “没有这样的文件或目录”

NSURLSESSION 后台下载多个

对 iOS 8 的 HTTP/2 支持