Background Fetch:是什么、工作原理和更新配置

作者: IT Sectr 发布日期: 2026-03-27 阅读时间: 8 分钟

Background Fetch — iOS机制,定期在后台唤醒应用程序以下载最新内容。系统分析用户行为并选择最佳的更新窗口。根据Apple, 2026的数据,应用程序有30到120秒的时间执行操作,之后系统会暂停或终止进程。

要点

  • Background Fetch — 用于在后台定期更新内容的iOS API。
  • 系统管理基于用户行为分析的唤醒频率。
  • 最小间隔通过UIApplication.minimumBackgroundFetchInterval设置。
  • 过时 — 从iOS 13+开始,该机制被视为传统,建议使用BGTaskScheduler。
  • 执行时间 — 最多30秒,之后系统强制结束任务。

什么是iOS中的Background Fetch?

Background Fetch — 是一个iOS API,允许应用程序在后台定期接收新数据。首次在iOS 7中与Background App Refresh机制一起引入。主要目标是让用户在打开应用程序时内容是最新的,无需等待加载。

与Push通知的区别

Push通知由服务器发起 — 它向设备发送信号,系统决定是否唤醒应用程序。Background Fetch由iOS本身根据设备使用模式发起。Push更适合紧急消息,Fetch — 用于计划的内容更新(新闻、社交媒体信息流)。

在后台任务生态系统中的位置

Background Fetch — iOS中几种后台执行机制之一。BGAppRefreshTask(iOS 13+)执行相同的任务,但具有更灵活的调度。Background Modes(音频、定位)— 用于持续操作。Silent Push — 由服务器发起的更新。Fetch对于支持iOS 12及更低版本的项目仍然适用。

  • Background Fetch — 周期性的,由系统发起,iOS 7+。
  • BGAppRefreshTask — 周期性的,由系统发起,iOS 13+。
  • BGProcessingTask — 长时间任务,iOS 13+。
  • Silent Push — 由服务器发起,iOS 7+。

Background Fetch的工作原理:架构和生命周期

iOS使用机器学习算法来确定唤醒应用程序的最佳时间。系统分析用户通常何时打开应用程序、使用多长时间以及返回频率。基于这些数据,iOS计算Background Fetch的窗口。

任务执行过程

当系统决定唤醒应用程序时,它会在AppDelegate中调用application(_:performFetchWithCompletionHandler:)方法。应用程序应下载最少量的新数据并使用三种状态之一调用completion handler:.newData(数据已下载)、.noData(没有新数据)或.failed(错误)。该状态会影响将来唤醒的频率。

Completion handler对调用频率的影响

.newData状态通知系统更新是有用的 — iOS可能会增加唤醒频率。.noData表示没有数据 — 频率保持不变或降低。.failed表示存在问题 — 系统降低频率以节省电量。重点应该是诚实的状态,而不是强制的.newData。

状态含义影响
.newData数据成功下载频率可能增加
.noData检查没有发现新数据频率保持不变
.failed网络或服务器错误频率降低

在Xcode项目中配置Background Fetch

要启用Background Fetch,需要执行两个步骤:在Xcode中激活capability并在代码中设置最小间隔。Capability位于Target — Signing & Capabilities — Background Modes — 勾选Background Fetch。没有这一步,系统将不会唤醒应用程序。

设置最小间隔

UIApplication.shared.setMinimumBackgroundFetchInterval方法设置了Fetch调用之间的最小时间(以秒为单位)。UIApplication.backgroundFetchIntervalMinimum值(大约15分钟)指示系统尽可能频繁地唤醒应用程序,以节能高效的方式。在application(_:didFinishLaunchingWithOptions:)中设置间隔是标准做法。

swift
func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey : Any]?
)-> Bool {
    UIApplication.shared.setMinimumBackgroundFetchInterval(
        UIApplication.backgroundFetchIntervalMinimum
    )
    return true
}

Info.plist和capability

在Xcode中启用Background Fetch时,它会自动更新Info.plist — 添加值为fetchUIBackgroundModes键。这是强制步骤:没有它,应用程序将不会收到performFetchWithCompletionHandler调用。可以通过P list Source或Build Settings检查是否存在。

Swift中Background Fetch的代码示例

让我们看一下新闻应用程序的Background Fetch完整实现。实现包括数据下载、缓存和调用completion handler。代码在AppDelegate中执行 — 系统调用fetch的唯一位置。

swift
func application(
    _ application: UIApplication,
    performFetchWithCompletionHandler handler: @escaping (UIBackgroundFetchResult) -> Void
) {
    let url = URL(string: "https://api.example.com/latest")!

    URLSession.shared.dataTask(with: url) { data, response, error in
        guard let data = data, error == nil else {
            handler(.failed)
            return
        }

        do {
            let articles = try JSONDecoder().decode([Article].self, from: data)
            cacheArticles(articles)
            handler(articles.isEmpty ? .noData : .newData)
        } catch {
            handler(.failed)
        }
    }.resume()
}

缓存已下载的数据

通过Background Fetch下载数据后,需要将其保存到本地存储中 — CoreData、UserDefaults或File Manager。当应用程序打开时,数据应该已经可用。使用带有后台上下文的CoreData进行线程安全的写入。保存后,在主线程中更新UI。

swift
func cacheArticles(_ articles: [Article]) {
    let container = NSPersistentContainer(name: "AppModel")
    container.performBackgroundTask { context in
        articles.forEach { article in
            let entity = ArticleEntity(context: context)
            entity.id = Int64(article.id)
            entity.title = article.title
            entity.body = article.body
        }
        try? context.save()
    }
}

测试Background Fetch

使用Simulator进行测试 — 在Xcode中选择Debug — Simulate Background Fetch。在物理设备上,需要等待系统决定执行fetch。为了加快速度,可以将最小间隔设置为1分钟,但在电池电量低时系统仍可能忽略它。

限制和陷阱

Background Fetch有一系列限制,在设计应用程序架构时需要考虑。最主要的是 — 系统完全控制调用频率,开发人员无法保证。即使设置了最小间隔,系统也可能数小时不调用fetch。

执行时间限制

系统为应用程序分配有限的时间来执行任务 — 通常最多30秒。如果应用程序在此期间没有调用completion handler,系统会强制终止进程并降低将来唤醒的频率。所有网络请求都应该是紧凑的 — 每次调用不超过1–2个。

电池依赖

iOS在调度Background Fetch时考虑电池电量水平。当电量低于20%时,唤醒频率降低。当启用Low Power Mode时,系统可能会完全关闭所有应用程序的后台更新。用户还可以在设置中为特定应用程序关闭Background App Refresh。

网络限制

从Background Fetch启动的URLSession以标准模式运行 — 不支持后台会话。对于大文件下载,请使用带有background configuration的URLSession。系统会在fetch结束后继续下载,但进度将不会被跟踪,直到下一次唤醒。

从Background Fetch迁移到BGTaskScheduler

从iOS 13开始,Apple建议使用BGTaskScheduler作为Background Fetch的替代品。BGTaskScheduler提供更灵活的调度、两种类型的任务(refresh和processing)以及带标识符的任务注册。迁移包括几个步骤,适用于所有新项目。

逐步迁移

第一步 — 通过BGTaskSchedulerPermittedIdentifiers键在Info.plist中定义任务标识符。第二步 — 通过BGTaskScheduler.shared.register在AppDelegate中注册任务。第三步 — 将performFetchWithCompletionHandler调用替换为传递给register的处理程序。第四步 — 调用submit来调度任务。

swift
// 之前(Background Fetch)
UIApplication.shared.setMinimumBackgroundFetchInterval(
    UIApplication.backgroundFetchIntervalMinimum
)

// 迁移后(BGTaskScheduler)
BGTaskScheduler.shared.register(
    forTaskWithIdentifier: "com.example.refresh",
    using: nil
) { task in
    self.handleAppRefresh(task: task as! BGAppRefreshTask)
}

let request = BGAppRefreshTaskRequest(
    identifier: "com.example.refresh"
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
try? BGTaskScheduler.shared.submit(request)

BGTaskScheduler的优势

BGTaskScheduler提供更多控制: BGProcessingTask用于长时间操作(最多10分钟),通过requiresNetworkConnectivity和requiresExternalPower设置执行条件,expiration handler用于优雅结束。系统也会分析应用程序的使用情况,但开发人员可以设置更精确的要求。

何时保留Background Fetch

如果应用程序支持iOS 12及更低版本,Background Fetch仍然是定期更新的唯一选择。BGTaskScheduler仅从iOS 13+开始可用。在这种情况下,使用包装器:通过if #available(iOS 13, *)检查BGTaskScheduler的可用性,并调用相应的API。

常见问题

iOS多久调用一次Background Fetch?

确切频率没有记录,取决于用户行为。系统分析用户打开应用程序的频率并相应地调整频率。平均而言,在活跃使用的情况下,fetch可能每小时被调用1–3次。在较少使用的情况下 — 每天1–2次。

为什么我的Background Fetch没有被调用?

检查三个条件:Background Fetch capability在Xcode中已启用,minimumBackgroundFetchInterval已设置,并且用户在设置中没有为应用程序关闭Background App Refresh。同时检查设备是否没有处于Low Power Mode,并且电池电量高于20%。

Background Fetch和BGAppRefreshTask有什么区别?

Background Fetch — 旧API(iOS 7),BGAppRefreshTask — 新API(iOS 13+)。BGAppRefreshTask提供更多控制:expiration handler、重新调度能力和状态检查。Background Fetch实现更简单,但灵活性较低。Apple建议对新项目使用BGAppRefreshTask。

可以通过Background Fetch下载大文件吗?

不建议。Background Fetch在时间上有限制(最多30秒)。对于大文件下载,请使用带有background configuration的URLSession — 系统会在fetch结束后继续下载。替代方案 — BGProcessingTask(iOS 13+),有最多10分钟的时间和充电条件。

Background Fetch消耗电池吗?

是的,每次唤醒都会消耗能量来启动处理器、初始化网络堆栈和下载数据。iOS优化频率以最小化影响。在正确实现的情况下 — 仅下载新数据、快速调用completion handler — 对电池的影响最小。

总结

  • Background Fetch — 用于在后台定期下载数据的iOS API,从iOS 7开始可用,建议替换为BGTaskScheduler。
  • 系统管理通过分析用户行为的调用频率 — 开发人员无法保证唤醒时间。
  • 三种状态的completion handler — .newData、.noData、.failed — 影响应用程序将来的唤醒频率。
  • 30秒限制 — 不要执行长时间操作或连续发出多个网络请求。
  • Capability是强制的 — Xcode中的Background Fetch + 在代码中设置minimumBackgroundFetchInterval。
  • BGTaskScheduler — 从iOS 13+开始的现代替代品,提供更多控制和两种任务类型。
  • 对于支持iOS 12及更低版本的项目,使用Background Fetch,并通过if #available检查BGTaskScheduler的可用性。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读