是否可以在应用程序处于后台时使用 AVAssetExportSession 的 exportAsynchronouslyWithCompletionHandler: 方法?

Is it possible to use AVAssetExportSession's `exportAsynchronouslyWithCompletionHandler:` method when the app is in the background?

我正在开发一个 iOS 应用程序,使用带后台配置的 NSURLSession 从相册上传视频。用户可以将多个视频排队上传(队列是串行执行的)。

单次上传包括:

  1. 使用 PHImageManager 的 requestAVAssetForVideo 方法获取对 PHAsset 的 AVURLAsset 引用。
  2. 正在将资源导出到临时目录(因为您不能直接从 AVURLAsset 的 URL 上传)。
  3. 正在使用 NSURLSessionUploadTask
  4. 上传资源

我可以对多个视频进行排队,并且该过程在前台运行良好。他们一个接一个地完成。

但是如果我排队几个视频然后后台应用。一旦执行到达 exportAsynchronouslyWithCompletionHandler: 阶段,它就会停止,直到我再次将应用程序置于前台。 (我知道这一点是因为我在本地通知中发布调试语句,在锁定屏幕上可见)。

是否可以在后台运行时使用exportAsynchronouslyWithCompletionHandler:

编辑 1 我在连接到调试器时对此进行了测试,但未连接时,该应用程序从不执行复制命令。但仅当应用程序再次置于前台时才这样做。

编辑 2 我发布了一个 similar question 关于使用 NSFileManager 的 copyItemAtURL:toURL:error: 是否是一个可行的替代方案(但我看到了相同的行为所以不要认为它是)。

一般来说,如果即使在用户离开应用程序后您只需要一点时间(最多几分钟)来完成某些任务,您只需从 OS 请求即可。请参阅后台执行章节中的 Executing Finite Length Tasks 部分。因此,当您调用 exportAsynchronouslyWithCompletionHandler 时开始后台任务,并在该方法的完成处理程序中结束它。

如果您也在使用背景NSURLSession。在这种情况下,如果应用程序在任务完成时不在前台,它会调用应用程序委托的 handleEventsForBackgroundURLSession 方法,该方法会传递一个 completionHandler 块。一必须:

  • 保存提供给handleEventsForBackgroundURLSessioncompletionHandler

  • 使用与原始后台会话相同的后台标识符实例化NSURLSession

  • 让会话调用适当的委托方法来完成任务;和

  • 会话将在它们全部完成后调用 URLSessionDidFinishEventsForBackgroundURLSession,此时您通常会调用我们最初在应用程序委托中收到的 completionHandler

在您的情况下,您需要将对已保存 completionHandler 的调用推迟到所有异步 exportAsynchronouslyWithCompletionHandler 处理程序也完成之后。有很多方法可以做到这一点(例如调度组等),但希望这能说明这个过程中涉及的移动部分。