【问题标题】:Why does Xcode simulator launch app with didEnterRegion call, while iPhone does not?为什么 Xcode 模拟器使用 didEnterRegion 调用启动应用程序,而 iPhone 没有?
【发布时间】:2019-07-28 14:12:51
【问题描述】:

我正在对基于位置的应用启动周期进行故障排除,该周期在 iOS 模拟器上运行良好,但显然无法在实际设备上启动应用。

我已经为进入和退出事件设置了 UNNotifications。模拟器和设备都会注册并显示这些通知。

接下来应该发生的事情是应用程序会经历一个启动过程,以这样一种方式设置应用程序的状态,即我无需连接到调试器就可以在打开应用程序时判断应用程序是否已启动从主屏幕。

在模拟器上,didEnterRegion 代码被调用,我可以使用调试器单步执行后续启动代码 - 成功。

但是,当我将设备取出(散步)时,我得到的只是 UNNotifications,并且没有应用程序启动(我可以从真实设备上应用程序的 UI 中得知)

我确定我需要改进我的测试策略(欢迎提出建议!),但在这一点上,我应该能够预期应用程序在模拟器和实际设备上的行为应该相同 - 事实并非如此。

为什么预期的结果会出现在模拟器上而不是设备上?

LocationService.swift

func handleRegionEnterEvent (for region: CLRegion) {
    ApplicationController.sharedInstance.didEnterRegion(region)
}

func handleRegionExitEvent (for region: CLRegion) {
    ApplicationController.sharedInstance.didExitRegion(region)
}

ApplicationController.swift

func didEnterRegion (_ region: CLRegion) {
    // Present Alert
    delegate?.handleUNEvent(note: "ENTER: \(region.identifier)")

    // Start launch cycle

}

AppDelegate.swift

extension AppDelegate: AppControllerDelegate {
    func handleUNEvent(note: String?) {
        // Show an alert if application is active
        if UIApplication.shared.applicationState == .active {
            guard let message = note else { return }
            Alert().showAlert(withMessage: "Application received UN while active: \(message)", title: "UNNotification")
        } else {
            // Otherwise present a local notification
            guard let body = note else { return }
            let notificationContent = UNMutableNotificationContent()
            notificationContent.body = body
            notificationContent.sound = UNNotificationSound.default
            notificationContent.badge = UIApplication.shared.applicationIconBadgeNumber + 1 as NSNumber
            let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
            let request = UNNotificationRequest(identifier: "location_change",
                content: notificationContent,
                trigger: trigger)
            UNUserNotificationCenter.current().add(request) { error in
                if let error = error {
                    print("Error: \(error)")
                }
            }
        }
    }
}

【问题讨论】:

  • 如果您收到通知,那么您的应用程序正在运行。如果您的应用已经在运行,您将不会接到 didFinishLaunching 的电话
  • @Paulw11 但是,“面向用户的通知将重要信息传达给您的应用程序的用户,无论您的应用程序是否在用户的设备上运行”,这不是真的吗? - Apple
  • 另外,该应用程序肯定没有在模拟器上运行,因为尚未附加调试过程(在“编辑Sheme...”中选择了手动启动选项
  • 您是否通过在didEnterRegion/didExitRegion 函数中执行代码来发布通知?如果您的代码没有运行,这些通知将如何发布?或者您是否使用区域触发器创建了通知?在问题中显示您的代码总是比描述您为消除歧义所做的工作要好。您是否已请求并收到“始终”位置许可?
  • 已编辑问题并包含代码。 “始终”授权...

标签: xcode debugging logging


【解决方案1】:

遗憾的是,模拟器与设备在报告的数据(例如,您不会获得速度)和呼叫流程方面存在很大差异......

需要检查的是确保您拥有与位置设置相关的特定位置权限的说明。对于输入区域,您可能希望确保您拥有“始终”访问权限。

还可能值得启用无线调试,并带着连接到设备的笔记本电脑四处走动,以使用调试器验证 didEnterRegion 确实没有被调用,并且代码中有一个错误应该显示你所在的 UI期待。至少,您可以更好地记录各种位置回调的状态。

【讨论】:

    【解决方案2】:

    发生了什么:在模拟器上执行的代码确实在设备上崩溃了,我没有查看来自设备的崩溃日志。这个问题来自一个既不是 ios 也不是核心位置特定的问题。

    这与选择适当的测试策略和使用所有可用信息有关,然后才能得出可能过早的结论。

    但是,当我将设备取出(散步)时,我得到的只是 UNNotifications,并且没有应用程序启动(我可以从真实设备上应用程序的 UI 中得知)

    我错误地认为 a) 应用程序未运行时出现的用户通知由系统呈现(作为横幅)和 b) 应用程序在另一个进程中启动。事实上,我自己的代码专门执行使这些通知出现的代码。面对面:从教程中复制代码以实现快速测试结果,甚至不试图理解代码的作用可能会导致我猜想。

    在 Xcode 中,插入您的设备并按 command-shift-2 以打开“设备和模拟器”窗口。在左侧选择您的设备并点击“查看日志”按钮以显示您的崩溃日志。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-29
      • 2012-03-21
      • 2013-03-15
      • 2014-05-08
      • 2011-02-16
      • 2012-05-09
      • 1970-01-01
      • 2018-07-27
      相关资源
      最近更新 更多