是否可以在应用程序处于后台时使用 AVAssetExportSession 的 exportAsynchronouslyWithCompletionHandler: 方法?
Is it possible to use AVAssetExportSession's `exportAsynchronouslyWithCompletionHandler:` method when the app is in the background?
我正在开发一个 iOS 应用程序,使用带后台配置的 NSURLSession 从相册上传视频。用户可以将多个视频排队上传(队列是串行执行的)。
单次上传包括:
- 使用 PHImageManager 的
requestAVAssetForVideo
方法获取对 PHAsset 的 AVURLAsset 引用。
- 正在将资源导出到临时目录(因为您不能直接从 AVURLAsset 的 URL 上传)。
- 正在使用 NSURLSessionUploadTask
上传资源
我可以对多个视频进行排队,并且该过程在前台运行良好。他们一个接一个地完成。
但是如果我排队几个视频然后后台应用。一旦执行到达 exportAsynchronouslyWithCompletionHandler:
阶段,它就会停止,直到我再次将应用程序置于前台。 (我知道这一点是因为我在本地通知中发布调试语句,在锁定屏幕上可见)。
是否可以在后台运行时使用exportAsynchronouslyWithCompletionHandler:
?
编辑 1
我在连接到调试器时对此进行了测试,但未连接时,该应用程序从不执行复制命令。但仅当应用程序再次置于前台时才这样做。
编辑 2
我发布了一个 similar question 关于使用 NSFileManager 的 copyItemAtURL:toURL:error:
是否是一个可行的替代方案(但我看到了相同的行为所以不要认为它是)。
一般来说,如果即使在用户离开应用程序后您只需要一点时间(最多几分钟)来完成某些任务,您只需从 OS 请求即可。请参阅后台执行章节中的 Executing Finite Length Tasks 部分。因此,当您调用 exportAsynchronouslyWithCompletionHandler
时开始后台任务,并在该方法的完成处理程序中结束它。
如果您也在使用背景NSURLSession
。在这种情况下,如果应用程序在任务完成时不在前台,它会调用应用程序委托的 handleEventsForBackgroundURLSession
方法,该方法会传递一个 completionHandler
块。一必须:
保存提供给handleEventsForBackgroundURLSession
的completionHandler
;
使用与原始后台会话相同的后台标识符实例化NSURLSession
;
让会话调用适当的委托方法来完成任务;和
会话将在它们全部完成后调用 URLSessionDidFinishEventsForBackgroundURLSession
,此时您通常会调用我们最初在应用程序委托中收到的 completionHandler
。
在您的情况下,您需要将对已保存 completionHandler
的调用推迟到所有异步 exportAsynchronouslyWithCompletionHandler
处理程序也完成之后。有很多方法可以做到这一点(例如调度组等),但希望这能说明这个过程中涉及的移动部分。
我正在开发一个 iOS 应用程序,使用带后台配置的 NSURLSession 从相册上传视频。用户可以将多个视频排队上传(队列是串行执行的)。
单次上传包括:
- 使用 PHImageManager 的
requestAVAssetForVideo
方法获取对 PHAsset 的 AVURLAsset 引用。 - 正在将资源导出到临时目录(因为您不能直接从 AVURLAsset 的 URL 上传)。
- 正在使用 NSURLSessionUploadTask 上传资源
我可以对多个视频进行排队,并且该过程在前台运行良好。他们一个接一个地完成。
但是如果我排队几个视频然后后台应用。一旦执行到达 exportAsynchronouslyWithCompletionHandler:
阶段,它就会停止,直到我再次将应用程序置于前台。 (我知道这一点是因为我在本地通知中发布调试语句,在锁定屏幕上可见)。
是否可以在后台运行时使用exportAsynchronouslyWithCompletionHandler:
?
编辑 1 我在连接到调试器时对此进行了测试,但未连接时,该应用程序从不执行复制命令。但仅当应用程序再次置于前台时才这样做。
编辑 2
我发布了一个 similar question 关于使用 NSFileManager 的 copyItemAtURL:toURL:error:
是否是一个可行的替代方案(但我看到了相同的行为所以不要认为它是)。
一般来说,如果即使在用户离开应用程序后您只需要一点时间(最多几分钟)来完成某些任务,您只需从 OS 请求即可。请参阅后台执行章节中的 Executing Finite Length Tasks 部分。因此,当您调用 exportAsynchronouslyWithCompletionHandler
时开始后台任务,并在该方法的完成处理程序中结束它。
如果您也在使用背景NSURLSession
。在这种情况下,如果应用程序在任务完成时不在前台,它会调用应用程序委托的 handleEventsForBackgroundURLSession
方法,该方法会传递一个 completionHandler
块。一必须:
保存提供给
handleEventsForBackgroundURLSession
的completionHandler
;使用与原始后台会话相同的后台标识符实例化
NSURLSession
;让会话调用适当的委托方法来完成任务;和
会话将在它们全部完成后调用
URLSessionDidFinishEventsForBackgroundURLSession
,此时您通常会调用我们最初在应用程序委托中收到的completionHandler
。
在您的情况下,您需要将对已保存 completionHandler
的调用推迟到所有异步 exportAsynchronouslyWithCompletionHandler
处理程序也完成之后。有很多方法可以做到这一点(例如调度组等),但希望这能说明这个过程中涉及的移动部分。