设置
我的iOS应用程序正在与BLE设备通信。作为对该通信中某些事件的响应,我想向用户提供触觉反馈。
为了支持像iPhone 7这样的旧手机,我决定使用UIFeedbackGenerator
,特别是UIImpactFeedbackGenerator
。
现在,当通过BLE接收到所述事件时,我调用feedbackGenerator.impactOccurred()
。
行为
在呼叫时,没有发生触觉反馈。但是系统仍然记得这些对UIFeedbackGenerator
的调用。
因为,当用户随后与UI元素进行交互时,对feedbackGenerator.impactOccurred()
的所有调用都被一次触发,并且触觉反馈被提供作为对该UI交互的响应。这对于用户来说是相当困惑的,他们当时并不期望触觉反馈。此外,如果随着时间的推移积累了足够多的呼叫,触觉反馈可能会非常强烈。
当这些被遗忘的触觉反馈调用累积到足够多时,系统似乎过载了;以下日志在控制台中生成几十次:
CAReportingClient.mm:295:-[CAReportingClient init]_block_invoke:无法与助手应用程序通信
无论如何,根据UIFeedbackGenerator
:的苹果文档,这可能是预期行为
请注意,调用这些方法不会直接播放触觉。相反,它会将事件通知系统。然后,系统基于设备、应用程序的状态、剩余电池电量和其他因素来确定是否播放触觉。
我的问题
您有使用核心蓝牙是否会改变CoreHaptics
或UIFeedbackGenerator
的行为的经验吗?这是我调试的起点,因为当我在本地模拟通信的所有部分时,触觉反馈工作得很好。
我已经尝试过的
- 从主/后台线程调用
UIFeedbackGenerator
- 用
UINotificationFeedbackGenerator
代替UIImpactFeedbackGenerator
- 预先在
UIFeedbackGenerator
上调用prepare()
事实证明,我在CoreBluetooth实现中没有给予足够的关注。我计划不断向特性发送数据的工作人员正在DispatchQueue.global(qos: .userInitiated)
中运行。
因为我和我的员工一起阻止了这个队列,CoreHaptics决定最好不要马上播放反馈。
这个故事的寓意是:注意你使用的队列。