干货分享!iOS10 SiriKit QQ适配详解

时间:2022-09-09 18:35:02

1. 概述

苹果在ios10开放了sirikit接口给第三方应用。目前,qq已经率先适配了siri的发消息和打电话功能。这意味着在ios10中你可以直接告诉siri让它帮你发qq消息和打qq电话了,听起来是不是很酷炫?

那么第三方应用使用siri的体验究竟如何?哪些应用可以接入sirikit?接入sirikit又需要做哪些工作呢?这篇文章会为你一一解答这些疑惑。

干货分享!iOS10 SiriKit QQ适配详解

图1 用siri发qq消息效果展示

2. sirikit简介

我们都知道siri是iphone手机中的智能语音助手,那么什么是sirikit呢?sirikit是苹果为第三方应用支持siri提供的开发框架。在官方文档中,sirikit将对不同场景的语音支持划分为不同的domain,目前,sirikit支持的domain包括:voip电话、发消息、转账、图片搜索、网约车订车、carplay和餐厅预定,也就是说如果你的应用中包含有这些功能之一,就可以考虑将这些功能接入到sirikit中啦。

实现sirikit相关功能时,我们并不需要真正对语音进行识别,语音的识别工作会由siri完成。siri识别完语音后,会将语音要完成的功能抽象成intent对象传递给我们,而我们的接入工作主要是与这些intent对象打交道,并不会涉及到自然语言处理(nlp)的技术。

关于sirikit的开发网上已有一些文章,也可参考苹果的官方文档sirikit programming guide,本文着重介绍qq的适配经验。

干货分享!iOS10 SiriKit QQ适配详解

图2 sirikit原理

3. sirikit接入

要实现sirikit的功能需要在xcode工程中添加intents extension的target,和其他extension一样, intents extension是一个独立于containing app进程运行的插件,主要用于处理和确认来自siri的intent请求。如果想让siri在处理app相关intent时提供一些自定义的界面,那么你就需要再添加intents ui extension的target,intents ui extension也是一个独立运行的插件(所以要完整的支持sirikit其实是需要添加两个target,有点蛋疼)。关于app extension的开发可以参考苹果的app extension programming guide。

我们以qq中的发消息功能为例说明一下sirikit的接入方法:

首先,我们需要在intents extentsion的info.plist文件中配置我们需要支持的siri intents,在intentssupported中加入insendmessageintent,如果需要在锁屏时禁用某个功能,则再在intentsrestrictedwhilelocked中加入相应项的intent,如图3所示。

干货分享!iOS10 SiriKit QQ适配详解

图3 intent extentsion info.plist配置

sirikit的接入主要分为intents extension和intents ui extension两部分,下面分别进行介绍。

intents extension

当我们对siri说“用qq发消息给王一然说你好”时,语音的识别将会由siri自动完成,siri会将识别好的内容展示在siri的界面。如图4所示,我们可以看到一个完整的发消息语句主要由四部分组成:

应用名:告诉siri要使用哪个app,siri会根据app的bundle displayname自动识别app的名称,无需额外注册。

发消息intent:告诉siri要使用发消息的功能,我们实测发现说发信息也是能识别,具体还有哪些词汇会识别为发消息的intent苹果没有在文档中说明。

消息接收者:告诉siri消息的接收者是谁,“王一然”是我qq好友的昵称。

消息内容:告诉siri你要发的消息内容是什么,这里的消息内容为“我很生气”。

干货分享!iOS10 SiriKit QQ适配详解

图4 确认发送消息界面

其中应用名和intent是必须的,不然siri无法抽象出你的“intent”。后两项如果缺省的话,我们可以在实现中要求用户进一步提供数据或者忽略。在识别完成后siri会将消息内容和接收者抽象成一个insendmessageintent传递给 qq的intent extension。

我们从图4还可以看到siri准确从我的语音中识别出我qq好友中昵称为“王一然”的好友,然而“王一然”并不是一个通用的短语,那么这是怎么做到的呢?奥秘就在于在qq运行时我们把所有qq好友的昵称同步到了siri云端,这样siri就可以识别出特定用户要使用的特定短语,详细同步方法可参考invocabulary的setvocabularystrings:oftype:方法。

每个domain的功能在siri中都有对应的intents,而每个intents都对应一个特定的handler协议。对于发消息来讲,对应的intent和handler协议分别为insendmessageintent和insendmessageintenthandling。只要实现insendmessageintenthandling协议中的相关方法,并在siri解析出insendmessageintent请求时用我们的insendmessageintenthandling对象去处理相关的发消息请求。具体的流程如图5:

干货分享!iOS10 SiriKit QQ适配详解

图5 siri发qq消息流程

1)resolverecipientsforsendmessage

对siri从intent中传递过来的接收者名称进行处理和确认,比如可以确认该名称当前是否在qq好友列表中,并将resolution result反馈给siri。resolution result代表了应用对intent处理后的结果,对于发消息来说,表1列举了几种可能的resolution results。

表1 send resolution result

干货分享!iOS10 SiriKit QQ适配详解

2)resolvecontent

与接收者的处理类似,在这个方法中可以对siri识别出的消息内容进行“修饰”,并且将resolution result反馈给siri,比如qq对一些消息里面的特殊词汇如“生气”做了emoji适配。

3)confirmsendmessage

这个方法的作用是确认是否要发送该消息,可以在这一步进行一些鉴权工作,鉴权通过后再确认发送,否则取消。确认可以发送后会调起确认发送界面,如图4所示。如果需要从containing app共享数据,具体的实现方案参考app group的shared container。

4)handlesendmessage

如图4,当用户点击了“发送”按钮或者用语音给出了发送指令时会最终进入到这个方法,在这个方法里我们需要实现发消息的逻辑,发送成功后可以调起消息发送成功的界面,如图6。

干货分享!iOS10 SiriKit QQ适配详解

图6 消息发送成功界面

intents ui extension

对于支持自定义界面的intent类型,可以在intents ui extension中提供更美观的自定义界面。 custom ui的实现相对较简单,和ios app的开发一样,都是通过uiviewcontroller的子类实现。我们需要在intents ui extension的info.plist文件中设置initial viewcontroller或者设置main storyboard,对于不同类型的intent的界面展示通过child viewcontrollers的方式实现差异化界面展示。

如图7所示,当接收到来自intents extension的response时,系统会唤起intents ui extension并加载initial viewcontroller,通过inuihostedviewsiriproviding协议的configurewithinteraction:context:completion:方法可以获取intent,比如在发消息功能中,在消息确认发送和发送成功后都会回调一次这个方法。根据intent对象的类型和状态,在收到相关intent的回调时present对应的child viewcontroller即可实现定制化的界面展示。

这里需要注意的是,intents ui extension的进程并不会在界面销毁后就退出,很可能只是在后台处于休眠状态,下次response到来时再被唤醒。

干货分享!iOS10 SiriKit QQ适配详解

图7 life cycle of an intents ui extension

4. 总结

总的来说虽然苹果这一次对sirikit开放的场景有限,但是从我们的适配经历来看苹果对siri还是非常重视的。另外,这是sirikit首次对第三方应用开放接口,所以不可避免存在一些问题。我们在开发过程中也确实遇到了一些sirikit本身的bug,大部分bug在向苹果反馈后都得到了解决,但是在语言识别方面siri依然存在一些缺陷,比如对中英文混合的场景识别依旧不太好。期待以后siri对中文的支持越来越好,也希望siri能够开放更多的场景给第三方应用适配。

​以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。