最近在做一款外设,搭配一款App,App中实现很多功能,集成了一套语音识别SDK,通过外设给App传输音频,通过SDK解析出具体的指令,去执行App中相关的功能。整体功能是这样,在iOS系统中,以上功能中有几个难点,很难解决或者是无法解决,只能避开。笼统的分以下几个点:
1).App在后台,外设能否拉起App
2).App被拉起之后,能否进行执行语音指令
3).App在后台,能否接收音频流,执行语音指令
上面这个问题是整个流程中最头疼的问题
1.首先要定义外设的形态,这里的外设可以是耳机,稍微变形一下可以是车载,录音笔,音响等。这里的外设就用耳机来代表。外设传输音频到App,无线场景下大部分都是采用蓝牙,蓝牙又分MFI认证的蓝牙设备和ble设备。
首先要说的是MFi认证的蓝牙设备,这类设备使用iAP协议同iPhone, iPad and iPod进行数据交互,传输性能好,稳定,但是成本比较大,设备需要苹果的官方检测很麻烦。当时查了一些资料,MFi认证的设备似乎是能解决上面说的几个问题。如图1所示,MFi认证的设备跟App商定好协议之后就能通过语音拉起App,但是这里有个坑,那段话我找不到了,意思是如果是usb模式的外设是可以直接拉起App,但是如果非usb模式的,拉起之前会出一个弹框,看图1 我们都以为这个alert是可选的,其实并不是,在某些模式下,必须是带alert的,如果拉起App需要Alert,让用户去确认,那也就没必要通过语音唤醒了,直接点击App好了,所以这条路基本就不考虑了。
但是外设是可以拉起Siri的,这个是固件需要支持的。这又为App打开了一条路,外设可以通过Siri打开App,这条路可行。但是Siri Shortcuts是iOS12之后才支持的。考虑低版本暂时没有想到好的解决方案。
苹果针对iap设备有一个background mode, 如图2 中的External accessory communication。设置了这个mode之后,在用户不主动杀死App,或者是系统不因为内存占用太高而杀死App,App理论上会一直在后台“活着”的,针对这个“活着”又是另一个话题了,这里的活着是假活的,也就是只能接收到来自外设传输的信息,所有其他的网络请求啥的都会被系统停止,在我的另一篇文章iOS 后台机制探索中讲到了这个,所以在后台这个模式只是给我们提供了一个入口,而且在接收到外设信息之后,系统只有10几秒的时候给App进行处理,具体多少秒,我没有实测,我在接收到消息之后,重连App中的socket连接进行数据发送这些操作都是能正常完成的。
所以总结以下,在通过MFi认证,使用iap进行数据交互的设备在我们这边的产品来看,能拉起App,但是拉起会出一个alert弹框 让用户确认,所以无法做到无用户参与的拉起App,如果想要通过外设去执行系统级别的操作,可以让外设接入Siri,可以通过Siri去打电话,接电话,查询天气等,同时在iOS12的系统上可以通过Siri打开应用。自家的App在设置了External accessory communication的background mode之后,能一定程度上保证App不被杀死,但是异常情况不可控,如果是iOS12 以上的系统可以通过Siri打开,但是iOS12以下的系统还是需要手动点击,先把App拉活了之后 再通过语音进行指令控制。但是就算设置了background mode之后,App也只能接收到来自iap的数据,无法完全保证所有的socket连接都不断,在每次接收到来自外设的数据时,还是需要本地做重连机制。
通过iap进行数据交互无论是产品定义还是功能实现都比较简单,因为苹果提供了很完整的文档,能实现啥不能实现啥都清清楚楚的展示出来了,而且iap数据传输带宽高,稳定性强,官方提供的demo直接就能用,需要App开发者要配置的东西很少,大部分的难点都在固件端,所以开发起来除了有后台的问题不好解决,其他都很愉快,但是如果是用ble进行音频传输就会有很多坑,下面一篇文章就是要说的不用iap进行这块的数据传输,改用ble的实现流程。