WatchOS WCSession sendMessage 唤醒杀死 iPhone 应用程序的调试和状态恢复问题

Posted

技术标签:

【中文标题】WatchOS WCSession sendMessage 唤醒杀死 iPhone 应用程序的调试和状态恢复问题【英文标题】:Debugging and state restoration concerns of WatchOS WCSession sendMessage waking killed iPhone app 【发布时间】:2016-03-30 22:24:29 【问题描述】:

我正在尝试将简单的 WatchOS 2.0 功能添加到我的应用程序中,以允许在手表上触发简单的操作并在我的 iPhone 上的主应用程序中产生效果。所有这些都取决于使用 WCSession 的 sendMessage 方法从手表发送消息

[[WCSession defaultSession] sendMessage:applicationData
                         replyHandler:^(NSDictionary *reply) 
                           //handle reply from iPhone app here
                           DbgLog(@"reply received=%@", reply);
                         
                         errorHandler:^(NSError *error) 
                           //catch any errors here
                           DbgLog(@"error received=%@", error);
                         
 ];

到目前为止一切正常,消息已发送,消息已接收,我的应用程序反应正确。我什至可以让我的应用程序在后台运行,一切似乎仍然正常(我可以在手表上看到 iPhone 是否对消息做出反应,因为 iPhone 将更新手表连接上下文,然后反映在手表上)。我现在只想开始调试边缘情况。

我主要的两个担心是......

如果系统被杀死,我该如何调试唤醒我的应用程序的系统。我显然无法从 Xcode 生成进程,如果我尝试附加到进程显然为时已晚,理想情况下,我希望能够尽早设置断点以查看事情是如何工作的。更糟糕的是,我可以依靠我猜测的大量日志并查看这些日志。只是想知道是否有尝试调试此场景的好方法?

最后,关于状态恢复,sendMessage 正在运行的这个被杀死的应用程序会发生什么情况。 IE。

我的应用运行时应用处于某种状态 (A) 我按下主页按钮使应用程序后台运行,当时为我的应用程序状态 (A) 执行状态编码。 然后应用程序位于后台。 然后我通过停止在 Xcode 中运行来强制终止该应用程序。 最后我从手表发送消息导致系统重新运行被杀死的应用程序。 在这个阶段,我预计会发生状态恢复加载,消息进来并被处理,将应用程序状态更改为状态 B,然后应用程序回到后台。

我的问题是应用程序在最初后台运行时仍将其状态编码保存在状态 A 中。

在处理完手表连接 sendMessage 后,有什么方法可以强制在后台进行新的状态编码?

当我下次正确打开我的应用程序时会发生什么,是否会发生状态恢复,这会使我们在处理完手表 sendMessage 后回到状态 A,它应该处于状态 B。我猜它仍在后台运行,所以无论有什么当应用程序在后台生成应用程序时发生,应该持续存在并且不应该发生新的状态恢复。但是,如果系统在状态 B 的背景下再次杀死应用程序怎么办。它是否理解这种情况需要新的状态编码来保存新的状态 B,或者它只是杀死应用程序而不做任何事情。如果是这样,那么当我们最终重新启动它时,我们可能会再次回到应用状态 A 而不是 B。

顺便说一句,刚开始尝试调试这类事情,但似乎无法连接我的调试器以重新运行我的 iPhone 应用程序实例。我注意到,当我执行应该唤醒被杀死的 iPhone 应用程序的 sendMessage 时,手表应用程序没有正确更新,即。电话应用程序未完全执行请求的操作。我目前对这个州发生的事情一无所知,但想知道状态恢复是否会阻碍。是否收到消息,唤醒应用程序,尝试对不存在的数据采取行动,因为尚未发生状态恢复,然后发生状态恢复.. 我第二次从手表发送消息时应用程序行为正确,所以它的好像初始消息唤醒了应用程序,但由于某种原因没有正确处理消息。一旦正确唤醒,但下一个 sendMessage 将正常处理。

抱歉,当 iPhone 应用程序从 sendMessage 调用后台重新运行时,我发现文档相当模糊。有人有什么想法吗?非常感谢您的时间!干杯!

【问题讨论】:

【参考方案1】:

背景和状态恢复:

在后台启动(然后终止)的应用将永远不会保存状态,因为它永远从前台转换到后台(即发生状态保存时)。

来自Preserving and Restoring State:

UIKit 会在适当的时候保留您应用的状态,例如当您的应用从前台移动到后台时。

它不保存状态的原因是因为它是直接启动到后台的。

来自The App Life Cycle:

此外,直接在后台启动的应用会进入[后台状态]而不是非活动状态。

调试在后台启动的应用:

至于在应用程序从终止状态在后台启动时附加到应用程序,a question which already provides the correct approach 适用于这种情况。

如果您对此有具体问题,请与该答案的作者发表评论。

【讨论】:

我们添加到此答案中的所有 cmets 都去了哪里? 状态恢复只恢复视图控制器。由于答案确定没有机制可以仅在后台使用更新的详细信息重写保存的状态,因此您真正遇到的问题是如何在 any 设备上发生更改时使所有设备保持最新状态。 您需要一种不同的方法,例如 iCloud,以便在设备进入前台后保持设备同步。 或许可以寻找这个新问题的相关答案,因为关于协调和合并来自多个来源的数据的讨论是无关的对于这个特定的问题和答案。 谢谢,我最终使用了今天的小部件共享用户默认值,该默认值会在后台处理时更新,以确保对任何状态恢复进行修补以匹配最新状态。希望可以正常工作,没有任何 iCloud 复杂性。不过谢谢,你是对的。不同的问题,希望对我来说足够解决。

以上是关于WatchOS WCSession sendMessage 唤醒杀死 iPhone 应用程序的调试和状态恢复问题的主要内容,如果未能解决你的问题,请参考以下文章

WatchOS WCSession sendMessage 唤醒杀死 iPhone 应用程序的调试和状态恢复问题

WCSession 无法发送消息

如何诊断和解决 WCSession sendMessage(_:replyHandler:errorHandler:) 上的崩溃?

如何从 watchOS 应用打开 App Store?

从 iOS 应用检测用户的 watchOS 版本

WatchOS - 来自 iOS 的复杂功能更新