正常应用程序启动和 WatchKit 的 sendMessage 唤醒之间的区别?

Differences between normal app startup and a wakeup from WatchKit's sendMessage?

根据 docs,从 WatchKit 应用程序发送 sendMessage 将唤醒处于非活动状态的 iPhone 应用程序。

我想知道这样的唤醒应用程序启动和普通应用程序启动之间的区别。当然,后台进程与普通前台应用程序有很多区别。但是,我找不到关于该主题的详尽文档。

这是我目前的发现:

请不要认为这个问题是关于“不止一个问题”的。这个 post 的问题很明确:我想知道 didReceiveMessage 后台进程和普通进程之间的所有区别。在上面的列举中,我只是列出了我期望的或我到目前为止遇到的所有差异,以及缺乏关于这些主题的文档。

我认为后台模式只是一个UIKit概念。该应用程序作为常规应用程序启动(感谢 UIApplicationMain 函数),但您的应用程序 UI 未呈现。

这只是一个警告:这是一个过渡状态,您的应用程序可以随时暂停,简洁。 documentation清楚了。

常规 UIKit API 可用(如果不是这样,想象一下所有潜在的崩溃)。但是您不会收到任何外部事件,例如触摸。

一些外部任务,如请求权限、启动音频会话等可能也不可用。

您可以使用方案面板中的wait for the executable to be launched选项等待应用启动。

But when I tried it out, launchOptions was nil. Doesn't that contradict the docs?

遗憾的是 LaunchOptions 并未涵盖应用启动的所有方式。所以如果你看到它 nil 那么你的情况也是其中之一。

But there seems to be no difference in mainScreen in the background process.

这是真实的,也是预料之中的。一切都使用主线程启动。参见

Is there a way I can debug such a background process in XCode?

GaetanZ 已经回答过了。此外,您可以一起使用 os.log 和控制台。这给了你一个更现实的方法。 Xcode 处理中断并不有趣。 wait for the executable to be launched 方案更改通常会使调试变得非常缓慢,或者经常 Xcode 只是断开连接甚至抛出奇怪的错误并且应用程序被杀死,甚至没有让您选择再次附加到调试器。

我经常使用 phone 完全重启。然后使用 oslog 查看我的应用程序发生了什么,而无需 Xcode 连接。有关更多信息,请参阅 .

重新启动不同于用户终止,因为在用户终止后通常不会启动。也就是说,如果 user 与他们的手表互动,我认为 OS 不会限制应用程序启动 - 即使在用户终止后也是如此。因为用户参与胜过一切。

However, the whole Javascript part of the app did not run (which is kind of expected, because in a background process, we do not need any React UI).

然后您还说“这是意料之中的,因为在后台进程中,我们不需要任何 React UI”

我对 React 知之甚少,但如果你说这是预期的,我也很困惑你的问题是什么。

但是如前所述,AppDelegate 经历其整个生命周期的部分是预期的。

您需要添加大量日志以查看您在哪里有不同的代码路径。

大多数开发人员不知道将应用程序启动到后台会一直运行到应用程序的根 viewController 及其所有子视图控制器和其他东西。但你是通过艰难的方式学到的。就像我一样。恭喜!

但是,一旦您了解了这一点,接下来的事情就是确保您的应用程序不会进入不同的代码路径,即在正常启动时您会得到 WillBecomeActivewillEnterForeground,因为启动到后台你会得到别的东西。我不确定现在是什么。 我认为WillBecomeActive & didEnterBackground。不确定。

或者就像你可能没有在事情发生之前设置你的 webview 的委托并且你错过了它的回调。

记住应用程序处于后台状态并不意味着事情会在后台队列中执行。一切都在相同的 queue/thread 上执行,就像在前台应用程序中一样。唯一不同的是 OS 在没有为他们配置应用程序时通常会限制网络调用。

可能这就是正在发生的事情。就像 OS 不希望 webview 在未通知应用程序正在使用和后台任务时进行网络调用 here or here