swift 如何在iOS上后台运行代码?不确定哪种方法有意义[关闭]

tct7dpnv  于 11个月前  发布在  Swift
关注(0)|答案(1)|浏览(88)

已关闭。此问题需要更多focused。目前不接受回答。
**要改进此问题吗?**更新此问题,使其仅针对editing this post的一个问题。

4天前关闭。
Improve this question
我正在尝试设置后台HTTP上传请求(将文件从用户的手机同步到服务器),该请求在我的Swift应用程序中定期触发。我对何时运行没有严格的要求(它可以在一夜之间或一整天发生)。
我知道苹果在iOS上为后台任务提供了几个API(beginBackgroundTaskBGAppRefreshTaskRequestBGProcessingTaskRequestURLSession upload vs. background session).我已经看到this post on the Apple developer forums试图解释差异以及何时使用-以及Apple's page on the subject,但我仍然不清楚其中一些在实践中是如何工作的,因此,我应该为我的用例使用哪些。
我的问题:

  • 如何在 * 后台 * 安排定期文件上传任务?
  • 我假设我应该使用BGProcessingTaskRequest,因为我不知道这个任务需要多长时间(可能只是同步1-2个文件,也可能是数百个),我不在乎它是否运行过夜
  • 如何确保在关闭应用程序后 * 前台 * 任务能够完成?(即当用户在应用程序中手动启动同步时)
  • 来自苹果在URLSessionUploadTask上的页面:“与数据任务不同,你可以使用上传任务在后台上传内容。”
  • 这是否意味着如果用户关闭应用程序,我使用URLSession.shared.upload()发出的任何请求都将自动在后台运行?即使是使用completionHandler版本,还是必须使用completionHandler版本?
  • 如果我使用URLSession.shared.upload()来保证我有更多的时间来完成上传,我需要调用beginBackgroundTask吗?
  • 那么顺序请求(即应用关闭时尚未启动的请求)呢?基于此SO响应,听起来我可能需要提前并行触发所有上传?https://stackoverflow.com/a/53949607/2359478
  • 我应该考虑URLSessionConfiguration.background作为我的用例吗?听起来我使用beginBackgroundTaskBGProcessingTaskRequest,那么这可能是不必要的?

谢谢你,谢谢

oxf4rvwz

oxf4rvwz1#

首先,在iOS中不可能生成任何类型的“周期性”(即以特定时间间隔发生)事件,而且这些事件会无限期地持续下去。但听起来你并不需要这样做。当用户没有更改任何数据时,也没有必要将数据同步到服务器。
您所描述的用例正是后台传输的设计目的。虽然我们通常以downloading large files的形式来讨论它们,但同样的技术也适用于上传。后台上传将继续在后台运行,即使您的应用被终止。它们完全由操作系统处理,而不是由您的应用处理。
为了使上载任务继续在后台运行,需要在支持后台的URLSession上创建这些任务。默认的.shared会话不支持后台。
类似于后台下载文档中的描述,步骤如下:

  • 使用.background(withIdentifier:)建立背景URLSessionConfiguration。
  • 您可能希望将.sessionSendsLaunchEvents设置为false,以便在上传完成时不会重新启动应用。
  • 设置.isDiscretionary只是一个判断。根据你的描述,你可能需要这个选项。但是如果这是一个同步引擎,请小心。在上载运行之前,可能需要很长时间。
  • 使用配置集,创建URLSession。
  • 使用uploadTask(with:fromFile:)创建任务。不能在此处使用完成处理程序或async版本。只能从磁盘上载文件。
  • 您可能需要设置earliestBeginDate以延迟上载。如果在上载开始前有新版本要同步,则这样可以更轻松地取消上载。
  • 设置countOfBytesClientExpectsToSendcountOfBytesClientExpectsToReceive有助于系统适当地调度任务。
  • resume()开始。

当你的应用启动时,你可以使用相同的标识符(通常只是一个静态字符串)重新创建会话,并使用getTasksWithCompletionHandler获取所有正在进行的任务的列表。如果你想创建一个新任务,这将允许你取消尚未开始的上传。
您可能不需要beginBackgroundTask,除非设置同步需要很长的时间。如果是这样,则可以使用beginBackgroundTaskendBackgroundTask来将该设置括起来,以帮助防止其被中断。
您也可能不需要BGProcessingTaskRequest。我可能会在前台安排所有同步操作。但是如果准备同步需要大量时间或电池,那么将所有这些工作都推到BGProcessingTaskRequest中可能是有意义的,并在最后开始上传。这就是它们的作用。但是,仅仅为了执行上传并不需要它。这与指定isDiscretionary的一个。
您可以选择将所有上传内容合并到一个文件中并创建一个上传请求,还是创建数百个小型上传请求,这两种方法各有优点,这取决于你的同步引擎是如何工作的。这个系统绝对有能力毫无问题地处理数百个请求。但是我建议你设置taskDescription来帮助你跟踪任务。它甚至可以用来编码有关任务的有用数据。它的内容完全由您决定。您还应该注意使用taskIdentifier,它将唯一地标识每个任务。

相关问题