跳过主要内容
iOS Capacitor 教程

为什么 iOS 停止后台位置更新

为什么 iOS 停止后台位置更新:Capacitor 应用程序的暂停、后台模式、授权、自动暂停、精度和修复每种原因的方法。

文章来源

马丁·多纳迪厄

作者

瓦莱里娅

审阅者

乔丹

编辑

iOS 停止后台位置更新

iOS 停止后台位置更新是因为它暂停了您的应用程序,而不是 Core Location 失败。除非应用程序声明了位置后台模式,启用了后台更新,并在前台时启动它们,否则 iOS 几秒钟后会冻结进程并排队或丢弃修复。这份指南列出了我们在 __CAPGO_KEEP_0__ 应用程序中看到的每种原因,包括每种原因的修复方法,并展示了如何处理它们。 CLLocationManageriOS 停止后台位置更新是因为它暂停了您的应用程序,而不是 Core Location 失败。除非应用程序声明了位置后台模式,启用了后台更新,并在前台时启动它们,否则 iOS 几秒钟后会冻结进程并排队或丢弃修复。这份指南列出了我们在 Capacitor 应用程序中看到的每种原因,包括每种原因的修复方法,并展示了如何处理它们。 @capgo/background-geolocation iOS 停止后台位置更新是因为它暂停了您的应用程序,而不是 Core Location 失败。除非应用程序声明了位置后台模式,启用了后台更新,并在前台时启动它们,否则 iOS 几秒钟后会冻结进程并排队或丢弃修复。这份指南列出了我们在 __CAPGO_KEEP_0__ 应用程序中看到的每种原因,包括每种原因的修复方法,并展示了如何处理它们。

iOS 后台应用的处理

当用户滑动主屏幕或锁定手机时,iOS会给应用程序一个短暂的窗口,然后暂停它。暂停的应用程序不会获得CPU时间。对于Capacitor应用程序,这意味着两者——原生侧和WebView——都停止运行,因此JavaScript回调也停止触发。

苹果公司为使用位置的应用程序做了一个例外。如果应用程序配置为在后台使用位置,并且在前台启动了一个活跃的位置会话,iOS会继续运行它并继续传递更新。以下内容都是关于满足该合同,以及系统故意打破它的案例。

原因1:缺少位置后台模式

没有 location 在 UIBackgroundModes,无论你添加多少code也无法保持更新流动。 ios/App/App/Info.plist:

<key>UIBackgroundModes</key>
<array>
  <string>location</string>
</array>

无论__CAPGO_KEEP_0__如何,都无法让更新流动。将其添加到

您还可以在Xcode中启用它, Signing &amp; Capabilities,Background Modes,Location updates。它是一个plist键,而不是一个特权,因此不需要更改配置文件。 allowsBackgroundLocationUpdates后台模式的原生属性是 true 在plist中没有开启后台模式会导致app崩溃。Capgo插件会自动为您设置它,当您传递 backgroundMessage to start()所以 plist 键必须在您发布应用之前存在。

App Review 检查背景模式是否合理。 在审阅笔记中说明使用它的功能,并确保该功能可供审阅者查看。

原因 2:更新从后台启动

苹果的规则:如果更新在应用前台时启动,则后台更新会继续。尝试从静默推送、后台抓取或任务启动会话是不适用于标准位置更新的。 BGTaskScheduler 从用户动作或应用恢复开始跟踪:

原因 3:

import { App } from '@capacitor/app';
import { BackgroundGeolocation } from '@capgo/background-geolocation';

let tracking = false;

export async function startTracking() {
  if (tracking) return;
  tracking = true;
  await BackgroundGeolocation.start(
    {
      backgroundMessage: 'Recording your route',
      backgroundTitle: 'Route recording',
      requestPermissions: true,
      distanceFilter: 10,
      url: 'https://api.example.com/v1/points',
    },
    (location, error) => {
      if (error) return console.error(error);
      if (location) console.log(location.latitude, location.longitude);
    },
  );
}

// Re-arm when the user comes back, if the session should be active
App.addListener('appStateChange', ({ isActive }) => {
  if (isActive && shouldBeTracking()) startTracking();
});

declare function shouldBeTracking(): boolean;

原因 3: backgroundMessage 这是特定于 __CAPGO_KEEP_0__ 插件的最常见错误报告。如果

这是特定于Capgo插件的,并且是最常见的bug报告。如果 backgroundMessage 并且更新会在应用被挂起时停止。请在两种平台上传递消息。 在 Android 上,它还成为前台服务通知的文本。 allowsBackgroundLocationUpdates stays false 原因 3:

原因 4:授权级别错误,或仅允许一次

许多开发者认为他们需要始终跟踪背景。他们不需要。苹果文档表明,具有“当使用时”授权的应用程序在有活动位置服务时可以在后台运行,前提是后台更新已启用。

始终与其他事情有关:重新启动一个终止的应用程序。只有区域监控、重大变化位置和访问才能重新启动一个应用程序,并且只有始终。

两个用户选择悄悄地破坏背景跟踪:

  • 仅允许一次。 这是一个临时的“当使用时”授权,到应用程序停止使用时就会过期。下一次会话从“未确定”开始。
  • 在使用时,然后始终提示从未显示。 在您开始会话之前,请检查实际状态:

在 iOS 上,

import { BackgroundGeolocation } from '@capgo/background-geolocation';

const status = await BackgroundGeolocation.checkPermissions();

if (status.location !== 'granted') {
  await BackgroundGeolocation.requestPermissions({ permissions: ['location'] });
}

if (status.backgroundLocation === 'when_in_use') {
  // Background tracking still works for standard updates.
  // Explain why Always helps if you also rely on geofences.
}

返回 backgroundLocation 或 when_in_use or granted / always所以您可以显示正确的解释而不是猜测。

原因 5:Core Location 自动暂停更新

CLLocationManager.pausesLocationUpdatesAutomatically 默认值 true. 当 iOS 认为用户不在移动时,它会暂停更新以节省电池。对于一个 When In Use 应用程序,暂停会结束位置访问,直到应用程序再次启动,Core Location 不会自动恢复。

Capgo 插件设置 pausesLocationUpdatesAutomatically = false 在其本机 code 中,因此这个问题已经解决。如果您编写自己的本机 code,或者使用另一个插件,请先检查此属性。

原因 6:设备静止且过滤器很大

一个 distanceFilter 的大小为 50 米,手机坐在桌子上产生的更新为零。看起来像“跟踪停止”在您的日志中,但它正在按照设计工作。

  • 如果您需要在静止时收到心跳,请使用小或零 distanceFilter.
  • 使用 minIntervalMs 来限制本机 POST 的发送频率,而不是一个大距离过滤器。
await BackgroundGeolocation.start(
  {
    backgroundMessage: 'Vehicle tracking active',
    distanceFilter: 0,
    minIntervalMs: 120_000, // at most one native POST every 2 minutes
    url: 'https://api.example.com/v1/vehicle-points',
  },
  () => {},
);

原因 7:精确位置关闭

由于 iOS 14 用户可以关闭应用的精确位置,您仍然会收到更新,但它们是粗略的(几公里)并且到达得很少。检测到此问题(大值)并向用户解释为什么精确位置对于您的功能很重要。如果您开发了送货或健身应用,请在首次启动时显示此信息,而不是在一次不成功的旅程之后。 accuracy 原因 8:用户终止了应用

原因8:用户终止了应用

选项:

Options:

  • 添加 Always 授权的围栏(geofences)到重要地点,以便 iOS 可以在进入或退出时重新启动应用。
  • 发送一个推送通知,提醒用户重新打开应用,当您的服务器停止接收会话点时。
  • 原因 9:JavaScript 未运行,尽管原生代码在运行

原因 9:JavaScript 未运行,尽管原生代码正在运行

A subtle one. Native code can receive a location while the WebView is suspended, or while it is still alive but not processing timers or network calls quickly. If you send points with fetch 原因 7:精确位置关闭

使用插件的 url 选项。每个点从本机code以相同的JSON发送,类型加上 Location type plus "source": "native"为了背景工作超出位置,请阅读

如何在__CAPGO_KEEP_0__中工作的背景任务 背景任务在Capacitor中是如何工作的 原因10:低功耗模式和热状态 @capgo/capacitor-background-task.

原因 10:低功耗模式和热状态

蓝色指示器

当使用位置的背景应用程序具有在使用时授权时,iOS会在状态栏中显示一个蓝色胶囊。__CAPGO_KEEP_0__插件设置

When an app with When In Use authorization uses location in the background, iOS shows a blue pill in the status bar. The Capgo plugin sets showsBackgroundLocationIndicator context true 为了后台会话,这是用户期望的,也是审查员在寻找的。不要试图隐藏它,用户信任它。

一个测试计划可以捕捉这些bug

模拟器测试不足以满足后台位置的需求。使用一个真实的iPhone并且:

  1. 构建一个发布配置,而不是仅仅是调试。调试构建附加到Xcode会得到不同的生命周期处理。
  2. 在前台启动一个会话,锁定手机,走路或开车20分钟。
  3. 重复使用“允许一次”,使用精确位置关闭,使用低功耗模式。
  4. 检查你的服务器日志而不是仅仅你的应用内日志。 source: "native" 在会话期间强制退出并确认你的应用在下一次启动时解释了发生了什么。
  5. 如果你需要一个设备的UDID来进行adhoc构建,iOS UDID finder

可以从Safari获取。如果你没有一个mac机器并且Xcode 26来进行构建, iOS会停止后台位置更新。 A test plan that catches these bugs Capgo 构建 可以在云端生成签名的 iOS 构建。

故障排查清单

症状 可能原因 解决方案
停止几秒钟后锁定 否 location 后台模式或无 backgroundMessage 添加 plist 键并传递 backgroundMessage
启动时崩溃 allowsBackgroundLocationUpdates 无后台模式 添加 UIBackgroundModes → location
只工作一次,之后就不再 用户选择了仅此一次 解释并再次询问,或者发送到 openSettings()
停用时 大 distanceFilter 降低它,使用 minIntervalMs
点之间很远,精度低 精确位置关闭 要求用户启用它
滑动后停止 用户终止了应用 iOS预期,使用地理围栏重启
原生获得积分,服务器不 JavaScript fetch 在回调中 使用 url 选项

运输修复

这些修复中,大部分涉及原生或native配置,因此需要一个新的App Store构建。JavaScript部分,如权限说明、引导文本和重试逻辑,可以通过 Info.plist __CAPGO_KEEP_0__ Capgo 实时更新 一旦原生构建发布后

如果您正在决定使用插件,我们的 Transistorsoft 和免费 Capgo 插件 涵盖了权衡。

Capacitor 应用程序的即时更新

当 Web 层面的 bug 在实时更新时,通过 Capgo 直接将修复推送给用户,而不必等待 App Store 的审批。用户在后台即可获得更新,而原生代码的变更仍然在正常的审批路径中。

最新博客

Capgo 给您所需的最佳见解,帮助您创建真正专业的移动应用。