iOS 15 在进入 BLE 信标区域时不会唤醒应用

Posted

技术标签:

【中文标题】iOS 15 在进入 BLE 信标区域时不会唤醒应用【英文标题】:iOS 15 does not awake app while entering BLE beacon region 【发布时间】:2021-11-14 18:50:31 【问题描述】:

我的 ios 应用中有 BLE 信标检测功能。这意味着如果用户打开了蓝牙和位置,并且如果用户进入信标的范围,系统会自动唤醒应用程序,如果它没有运行(终止状态)。

这在 iOS 14 及更低版本上运行良好。昨天我将我的设备更新到 iOS 15,即使我在设置中启用了“始终”位置权限,应用程序在进入 ble 信标区域时也不再被唤醒。

有什么想法吗?

【问题讨论】:

为了完成诊断需要尝试的几件事: (1) 如果您手动启动应用程序,它会从前台检测到吗? (2)如果您然后退出该区域并将应用程序移到后台,它可以从后台再次检测到吗? (3)如果前两个测试成功,那么如果你退出该区域,重启你的手机(重启后等待5分钟而不启动你的应用程序)然后进入信标范围,它检测到吗? @davidgyoung 我可以确认前两个测试工作正常。第三次测试没有成功。进入该区域时,Beacon 未检测到/启动应用程序。 @davidgyoung 有什么更新吗? 我在不同的函数中添加了本地通知,例如 EnteredRegion、LeftRegion、DidDeterminedState 和 DidRangeBeacons。如果我完全关闭应用程序,超出范围并返回该区域,运行 iOS 14 或更低版本的设备会唤醒,我会收到来自 EnteredRegion、DidDeterminedState 和 DidRangeBeacons 的通知。但我在运行 iOS 15 的设备上没有收到任何通知。前提是我已在所有设备上启用“始终”位置权限。 在我们关于此问题(特别是信标监控)的大量错误报告中,状态已更新为“确定的潜在修复 - 用于未来的操作系统更新”。 【参考方案1】:

我的测试表明,iOS 15 在进入信标区域时成功地将应用从停止状态启动到后台。

测试步骤:

    在我的 iOS 14.8 手机上安装这个应用程序:https://github.com/davidgyoung/CoreLocationRegionLaunchDemo

    运行应用程序,始终授予通知和位置权限。

    转到设置并验证位置权限始终是

    打开信标,验证进入通知到达。然后关闭信标,验证退出通知到达。

    重启手机。等5分钟。打开信标,然后验证进入通知到达。关闭信标并验证退出通知到达。

    升级到 iOS 15。

    等待 5 分钟。

    打开信标。验证进入通知到达。

查看屏幕截图——抱歉它们很丑,但我必须先完成 XCode 13 的巨大下载,然后才能将屏幕截图直接发送到我的电脑。

【讨论】:

我看到了一个奇怪的行为。重启测试后,应用程序在后台启动。 DidRange 开始被调用。如果我锁定屏幕,我不会收到 didRange 通知。一打开显示器,我就开始再次收到 didRange 通知。 我试过你的代码,它运行良好,但有一个问题我在这里解释过***.com/questions/69315374/… 很高兴听到!如果这回答了这个问题,请将此答案标记为已接受,以便其他人能够找到解决方案。【参考方案2】:

经过反复试验、测试和与 Apple 的对话,我可以确认这不是区域监控的错误,而是 Apple's new prewarming feature in iOS 15 的错误。

简而言之,iOS 15 将在 iOS 认为用户会使用的后台静默启动应用程序。在我们的测试中,这大约每半小时发生一次。它使应用启动感觉更快,因为一堆应用已经加载并准备就绪。

如果 Apple 预热您的应用,而用户没有完全启动它,然后区域监视器需要通知您的应用,则不会发生这种情况。有时区域监控会提醒您的应用,有时则不会。如果您的应用程序“冷”,它将起作用。如果您的应用程序在内存中,它将工作。如果您的应用处于这种预热状态,那么您就死定了。

重新启动整个手机是可行的,因为您正在驱逐任何处于预热状态的应用。

我从 Apple 那里得知这确实是多个错误,有些已修复,有些尚未修复。 iOS 15.2 测试版中的注释还特别提到这可能也会影响 HealthKit。

解决该错误的解决方案是在 main.m 中检测 Apple 何时预热您的应用程序和 exit。这不允许您的应用在 Apple 预热时启动,并在时机成熟时强制您的应用完全启动。

这是main.m 内部main() 方法的代码。请注意,添加 iOS 版本检测是谨慎的做法,因此当 Apple 确实修复此问题时,它最终可能会被逐步淘汰和删除。

double systemVersion = [[UIDevice currentDevice] systemVersion].doubleValue;
if (systemVersion >= 15.0) 
    NSDictionary* environment = [[NSProcessInfo processInfo] environment];
    BOOL prewarmed = false;
    for (NSString *key in environment.allKeys) 
        if ([key.lowercaseString containsString:@"prewarm"]) 
            prewarmed = true;
            break;
        
    

    if (prewarmed) 
        exit(0);
    

【讨论】:

【参考方案3】:

很奇怪,就我而言,重启似乎可以解决问题。

【讨论】:

但我从没想过重启(直到我看到 davidgyoung 的回答),更不用说客户了。对于依赖此功能的在线应用来说,这将是一场灾难。 用户不希望每次遇到此问题时都重新启动手机。还有其他解决方法吗? @JasonRoy 在我的情况下,只需要重新启动一次,然后它就可以正常工作(但也很难通知每个用户重新启动)。但是不知道会不会再次出现问题。

以上是关于iOS 15 在进入 BLE 信标区域时不会唤醒应用的主要内容,如果未能解决你的问题,请参考以下文章

在信标区域内每 10 分钟更新一次应用程序

是否在相同的 BLE 扫描中收到信标监视和测距回调

在后台 iOS Xcode 中获取信标通知

在iOS中测距和监控时如何获取信标的MAC地址

iOS 在后台监控/测距信标会消耗大量电池

iOS8 - BLE 唤醒应用