NSURLSession 导致 0B 图像上传到 GCS

Posted

技术标签:

【中文标题】NSURLSession 导致 0B 图像上传到 GCS【英文标题】:NSURLSession resulting in 0B images uploaded to GCS 【发布时间】:2020-04-29 22:56:10 【问题描述】:

我正在使用配置为后台会话的 NSURLSession 将多个图像上传到 GCS 中的存储桶。在一项测试中,使用了 26 张图片,每张大约 10 MB。测试是在强大的 wifi 连接和接近 100% 的电池(如果不主动充电)下进行的。我正在创建这个 NSURLSession 应用程序是后台的,并通过后台任务到期处理程序通知。

NSURLSession 代码:

let config = URLSessionConfiguration.background(withIdentifier: identifier)
config.waitsForConnectivity = true
config.allowsCellularAccess = true
config.isDiscretionary = false

let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
session.sessionDescription = identifier

创建上传请求:

for (signedGCSURLDestination, image) in images 
  let request = URLRequest(url: signedGCSURLDestination, method: .put)
  request.headers.add(name: "Content-Type", value: "image/jpeg")

  let task = session.uploadTask(with: request, fromFile: file)

  task.taskDescription = identifier
  task.resume()
 

最终,GCS Bucket 中的图像大小均为 0B。在转换到后台 NSURLSession 之前,我们在应用程序前台使用 Alamofire,这些图像上传到存储桶中就好了。

我开始调查使用后台处理任务,以便在应用程序最小化时继续使用 Alamofire 代码,但这是与 NSURLSession 根本不起作用的单独问题。

【问题讨论】:

您实现了URLSessionTaskDelegate 方法吗? urlSession(_:task:didCompleteWithError:) 报告的任何错误?使用 Charles 或 Wireshark 之类的工具观看上传也很有用,也许可以将您的 Alamofire 前台实现与此实现进行比较。 【参考方案1】:

一旦设备被锁定,正在上传的文件没有适当的权限。在我要上传的每个文件上设置completeUntilFirstUserAuthentication 属性解决了这个问题。

FileManager.default.setAttributes([FileAttributeKey.protectionKey: FileProtectionType.completeUntilFirstUserAuthentication],
                                           ofItemAtPath: path)

我想上传是在设备被锁定之前开始的,看起来 NSURLSession 上传似乎是并行发生的。所以所有文件的上传都可能开始了,因此文件占位符在 GCS 中存在于 0B,然后由于文件被锁定,它们从未完成。

【讨论】:

以上是关于NSURLSession 导致 0B 图像上传到 GCS的主要内容,如果未能解决你的问题,请参考以下文章

NSURLSession 上传任务超时

将图像文件从 IOS 上传到 Web 服务器

NSURLSession 是不是支持 FTP 上传?

iOS:如何增加 NSURLSession 上传任务的块大小?

Firebase Swift 3 使用 NSURLSession 将配置文件图像加载到 TableView

尝试使用 Alamofire 下载图像时,NSURLSession/NSURLConnection HTTP 加载失败