iOS / Swift:在应用程序处于后台时,从数据流服务接收回调而不推送通知

背景资料:

我正在编写一个应用程序,它使用PubNub框架将一个Raspberry Pi与一个iPhone直接耦合,用于每个用户。 Raspberry Pi使用Arduino作为从属设备来收集模拟数据,然后使用PubNub网络将该数据发布到同一频道上的唯一iPhone上。 利用iPhone接收的数据,它(在本地)确定是否需要提醒用户。 然后,当用户收到警报时,他们可以通过将数据(设置)发送回Pi来调整Raspberry Pi的当前状态,这将解决保证用户警报的问题。

问题:

当iPhone应用程序进入后台时,应该接收iPhone应该接收的Raspberry Pi发送的消息将不再被应用程序捕获,因此用户不再需要时通知。 第一个明显的解决方案是将保证警报的逻辑移动到Raspberry Pi本身,以便它可以使用Apple推送通知将这些警报发送给用户。 但是,问题在于我还在尝试跟踪Raspberry Pi连接是否已超时,因此如果发生某些意外断开连接,用户也会收到该问题的通知。 这个逻辑显然不能在Raspberry Pi本身,因为如果发生断开连接,那么它将无法将通知推送到iPhone本身。 有一个中间人服务器来监控设备的状态似乎是一个合乎逻辑的解决方案…但是我想要除了iPhone和Raspberry Pi之外的其他任何数据传输和处理,这显然是整个动机首先使用PubNub(在我的应用程序范围内)。

这不是PubNub特定的问题。 我只是引用它们来描绘一幅更清晰的画面。 另外值得注意的是,我不想伪造位置服务以使iOS获得连续的后台权限。 这是一个懒惰和草率的解决方案,具有不希望的开销。

问题:

如何在后台每隔15到30秒接收(或请求)一个短字符串,以确定是否应该发出警报。 这必须是可以实现的。 根据我对苹果文档的研究和阅读,我很清楚许多人会尝试回答“这是不可能的”。 我不欢迎这个答案 。 我在这里找到一个我以前无法找到的解决方案,或者之前未提出的解决方案。 我需要一位智能工程师为我的问题提出真正的解决方案或解决方案。

我提前真诚地感谢冠军工程师。

@JonW我读了你的问题和一些评论,直到我进入TL; DR点:)简短的回答是静音推送通知可能是你的一个问题的答案。另一个可能是PubNub Presence Webhooks 。 但我同意@ Paulw11服务器是最佳做法,最终, PubNub BLOCKS将是您的解决方案。

使用Apple静音推送通知进行后台处理

要进行一些简短的后台处理,您可以让您的RPi发布包含推送通知的消息(我相信您已经在做了)。 但是这个推送消息应该是一个无声推送通知 。 文档说这个:

当无声通知到来时,iOS会在后台唤醒您的应用程序,以便您可以从服务器获取新数据或进行后台信息处理。

…确保aps词典中没有警报,声音或徽章有效负载

完整的详细信息在我刚刚提供的链接中,但这里是一个示例消息有效负载,您将使用正确的aps格式在PubNub上发布。

 { "pn_apns": { "aps": { "content-available": 1, "data": { "temperature": "55", "humidity": "42%" } } }, "data": { "info": "This is the full realtime message.", "temperature": "55", "humidity": "42%" } } 

警告:静默推送通知仅在应用程序未处于终止状态时有效。 换句话说,它必须在后台空闲 – 不运行,而是空闲。 如果您强制终止应用程序(通过双击主页按钮从最近的应用程序列表向上轻扫)或在设备关闭然后再打开后不启动应用程序,则将忽略静默推送。

请参阅此徽章计数演示作为入门模板。 但正如@Paulw11所说,每30秒定期推送通知并不是一个好主意。 您应该将更新发送到服务器,该服务器可以在需要采取措施时向iPhone应用程序发送推送通知。

使用PubNub Presence Webhooks进行脱机通知

进一步了解服务器进程的最佳实践,您可以让服务器监视通道上RPi的存在 。 如果RPi通过显式取消订阅通道( leave事件)或通过网络断开( timeout事件) leave通道,则可以将消息POST到您的服务器REST端点(您提供我们在您的PubNub密钥上配置)。 如果发生这些事件中的任何一个,那么您可以将消息(包括静音推送有效负载)发布到iPhone应用程序以采取适当的操作。

PubNub BLOCKS – 无需服务器(看看妈妈,没有服务器!)

所以你说你想避免使用服务器。 使用PubNub BLOCKS ,您将能够避免使用自己的服务器 – 而是使用PubNub服务器

我不会在这里详细介绍太多细节,但您可以在BLOCK中编写一小部分JavaScript,以确定是否需要发送推送通知等等。

概要

现在,我认为你的静态推送原型很好地充实了你的用例。 但最终,您需要一个始终在线的流程,以确定何时需要发送推送通知。 当您的iPhone应用程序处于活动状态时,它可以从RPi接收实时消息,但在后台时,每30秒进行一次静音推送并不理想,Apple可能不允许这样做。