iOS如何在后台运行代码?不确定哪种方法有意义

问题描述 投票:0回答:1

我正在尝试设置在我的 Swift 应用程序中定期触发的后台 HTTP 上传请求(将文件从用户手机同步到服务器)。我对何时运行没有严格要求(可以在一夜之间或全天发生)。

我知道 Apple 为 iOS 上的后台任务提供了多个 API(

beginBackgroundTask
BGAppRefreshTaskRequest
BGProcessingTaskRequest
URLSession
上传与后台会话)。我已经在 Apple 开发者论坛上看到了 这篇文章,试图解释这些差异以及何时使用哪个 - 以及 Apple 关于该主题的页面,但我仍然不清楚其中一些是如何工作的在实践中,我应该将哪些用于我的用例。

我的问题:

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

ios swift nsurlsession urlsession background-task
1个回答
0
投票
首先,不可能在 iOS 中生成任何类型的无限期持续的“周期性”(即以特定间隔发生)事件。但听起来你并不需要那个。当用户没有更改任何数据时,无需将数据同步到服务器。

您所描述的用例正是后台传输的设计目的。虽然它们通常是在“下载大文件”方面讨论的,但相同的技术也适用于上传。即使您的应用程序被终止,后台上传也将继续在后台运行。它们完全由操作系统处理,而不是您的应用程序。

为了让您的上传任务继续在后台运行,需要在支持后台的 URLSession 上创建它们。默认 .shared

会话不支持后台。

与后台下载文档中的描述类似,步骤为:

使用

.background(withIdentifier:)
    创建后台 URLSessionConfiguration。
  • 您可能希望将 
    .sessionSendsLaunchEvents
  • 设置为 false,以便上传完成后您的应用程序不会重新启动。
  • 设置 
    .isDiscretionary
  • 是一个判断调用。根据您的描述,您可能需要此选项。但如果这是同步引擎,请小心。上传运行可能需要很长时间。
  • 设置好配置后,创建一个 URLSession。
  • 使用
  • uploadTask(with:fromFile:)
  • 创建任务。您不能在此处使用完成处理程序或
  • async
     版本。您只能从磁盘上传文件。
    您可能需要设置 
    earliestBeginDate
  • 来延迟上传。如果在上传开始之前有新版本需要同步,这样可以更轻松地取消上传。
  • 设置 
    countOfBytesClientExpectsToSend
  • countOfBytesClientExpectsToReceive
     有助于系统适当地安排任务。
    resume()
  • 开始。
  • 当您的应用程序启动时,您可以使用相同的标识符重新创建会话(这通常只是一个静态字符串),并使用 
  • getTasksWithCompletionHandler
获取所有正在进行的任务的列表。如果您想创建新任务,这将允许您取消尚未开始的上传。

您可能不需要
beginBackgroundTask

,除非设置同步需要花费大量时间。如果是这样,那么您可以用

beginBackgroundTask

endBackgroundTask
 将该设置括起来,以帮助防止它被中断。
您可能也不需要 BGProcessingTaskRequest。我可能会在前台安排所有同步操作。但是,如果准备同步需要大量时间或电池,那么将所有这些工作推送到 BGProcessingTaskRequest 中并在最后开始上传可能是有意义的。这就是他们的目的。但不需要它仅仅执行上传。这与指定 
isDiscretionary

相同。

© www.soinside.com 2019 - 2024. All rights reserved.