当前位置: 首页 > 科技观察

iOS10SiriKitQQ适配详情

时间:2023-03-13 12:03:36 科技观察

1.概述苹果在iOS10中向第三方应用开??放了siriKit接口。目前,QQ已率先适配Siri的消息和通话功能。这意味着,在iOS10中,你可以直接告诉Siri,让它为你发送QQ消息和拨打QQ电话。听起来很酷吗?那么在第三方应用中使用Siri是一种怎样的体验呢?哪些应用程序可以访问SiriKit?接入SiriKit需要做什么工作?本文将为您一一解答这些问题。图1使用Siri发送QQ消息的效果2.SiriKit简介我们都知道Siri是iPhone中的智能语音助手,那么SiriKit是什么?SiriKit是Apple为第三方应用程序提供的支持Siri的开发框架。在官方文档中,SiriKit将针对不同场景的语音支持划分到了不同的域中。目前,SiriKit支持的领域包括:VoIP通话、消息、传输、图像搜索、在线汽车预订、CarPlay和餐厅预订。也就是说,如果你的应用程序包含这些功能之一,你可以考虑将这些功能连接到SiriKit。在实现SiriKit相关功能时,我们不需要真正识别语音,语音识别会由Siri来完成。Siri识别语音后,会将语音要完成的功能抽象成一个Intent对象传递给我们,而我们的接入工作主要是处理这些Intent对象,不涉及自然语言处理(NLP)技术。网上已经有一些关于SiriKit开发的文章,也可以参考苹果官方文档SiriKitProgrammingGuide。本文重点介绍QQ的适配体验。图2SiriKit原理3.SiriKit接入要实现SiriKit的功能,需要在Xcode工程中添加IntentsExtension的target。与其他扩展一样,IntentsExtension是一个独立于ContainingApp进程运行的插件,主要用于处理和确认来自Siri的Intent请求。如果你想让Siri在处理App相关的intent时提供一些自定义的接口,那么你需要添加IntentsUIExtension的target。IntentsUIExtension也是一个独立运行的插件(所以要完全支持SiriKit,需要添加两个Atarget,有点蛋疼)。AppExtension的开发请参考Apple的AppExtensionProgrammingGuide。下面以QQ中的消息发送功能为例,来说明SiriKit的接入方式:首先,我们需要在IntentsExtension的info.plist文件中配置我们需要支持的siriIntents,在IntentsSupported中添加INSendMessageIntent。当某个功能被禁用时,在IntentsRestrictedWhileLocked中添加相应的Intent,如图3所示。图3IntentExtensioninfo.plist配置SiriKit访问主要分为两部分:IntentsExtension和IntentsUIExtension,下面分别介绍。IntentsExtension当我们对Siri说“用QQ发消息给王怡然打个招呼”时,Siri会自动完成语音识别,Siri会将识别到的内容显示在Siri界面上。如图4所示,我们可以看到一个完整的消息发送语句主要由四部分组成:应用名称:告诉Siri使用哪个应用,siri会根据应用的bundledisplayname自动识别应用名称,无需额外注册.Intentforsendingmessages:告诉Siri使用发送消息的功能。我们通过实际测试发现发送消息也是可以识别的。Apple没有在文档中指定哪些其他词将被识别为发送消息的意图。消息收件人:告诉Siri消息的收件人是谁,“王怡然”是我QQ好友的昵称。消息内容:告诉Siri你要发送的消息内容是什么,这里的消息内容是“我很生气”。图4确认发送消息界面应用名称和Intent是必填项,否则Siri无法抽象出你的“Intent”。如果最后两项是默认的,我们可以要求用户提供进一步的数据,或者在实现中忽略它们。识别完成后,Siri会将消息内容和接收者抽象成一个INSendMessageIntent传递给QQ的IntentExtension。从图4中我们也可以看出,Siri可以准确的从我的声音中识别出我QQ好友的昵称是“王怡然”。然而,“王亦然”并不是一个普通的词组,那么这到底是怎么回事呢?谜底在于,我们在QQ运行时将所有QQ好友的昵称同步到Siri云端,让Siri识别出特定用户想要使用的特定短语。详细的同步方法请参考INVocabulary的setVocabularyStrings:ofType:方法。每个领域的功能在Siri中都有对应的Intents,每个Intent对应一个特定的handlerprotocol。对于发送消息,对应的Intent和handler协议分别是INSendMessageIntent和INSendMessageIntentHandling。只需要实现INSendMessageIntentHandling协议中的相关方法,在Siri解析INSendMessageIntent请求时,使用我们的INSendMessageIntentHandling对象来处理相关的消息发送请求。具体流程如图5所示:图5Siri发送QQ消息流程1)ResolveRecipientsForSendMessage从Intent中处理并确认Siri传递过来的收件人姓名,比如可以确认该姓名当前是否在QQ好友列表中,以及将解决结果反馈给Siri。解析结果表示应用程序处理意图的结果。对于发送消息,表1列出了几种可能的解析结果。表1发送解析结果2)ResolveContent与接收方的处理类似。该方法可以对Siri识别的消息内容进行“修改”,并将解析结果反馈给Siri。愤怒”已适配emoji。3)ConfirmSendMessage方法的作用是确认是否发送消息。可以在这一步进行一些鉴权工作,鉴权通过后再确认发送,否则取消。确认可以发送后,会调用确认发送接口,如图4所示。如果需要共享ContainingApp的数据,具体实现方案参考AppGroup的SharedContainer。4)HandleSendMessage如图4所示,当用户点击“发送”按钮或语音发出发送指令时,最终会进入该方法。在这个方法中,我们需要实现发送消息的逻辑。发送成功后,可以调用消息发送成功界面如图6所示。图6IntentsUIExtensiononthemessagesendingsuccessinterface对于支持自定义接口的Intent类型,可以在意图UI扩展。CustomUI的实现比较简单。和iosapp的开发一样,都是通过UIViewController的子类来实现的。我们需要在IntentsUIExtension的info.plist文件中设置initialviewcontroller或者mainstoryboard,针对不同类型的Intent界面展示,使用ChildViewcontroller实现差异化的界面展示。如图7所示,当收到IntentsExtension的响应时,系统将调用IntentsUIExtension并加载初始视图控制器,可以通过INUIHostedViewSiriProviding协议的configureWithInteraction:context:completion:方法获取Intent。比如在消息函数中,在消息确认发送成功后会回调一次该方法。根据Intent对象的类型和状态,在接收到相关Intent的回调时,呈现对应的ChildViewcontroller,实现自定义界面显示。这里需要注意的是,IntentsUIExtension的进程在界面销毁后并不会退出,很可能在后台处于休眠状态,等下一次响应到来时才会被唤醒。图7一个IntentsUIextension的生命周期4.总结总的来说,虽然这次苹果对SiriKit的开放场景进行了限制,但是从我们的适配体验来看,苹果对Siri还是很重视的。另外,SiriKit是第一次对外开放第三方应用的接口,难免存在一些问题。在开发过程中,我们确实遇到了SiriKit本身的一些错误。大部分错误在反馈给Apple后得到解决。不过Siri在语言识别方面还是存在一些缺陷。比如中英文混合场景的识别还是不太好。好的。期待Siri以后对中文的支持会越来越好,也希望Siri能够开放更多第三方应用适配的场景。更多精彩内容,请关注bugly的微信公众号:腾讯Bugly是一款专为移动开发者打造的质量监控工具,帮助开发者快速便捷地定位线上应用崩溃问题及解决方案。智能合并功能可帮助开发人员根据根本原因对每天报告的数千起崩溃进行分类。每日每日报告将列出影响最多用户的崩溃。精准定位功能帮助开发者定位问题代码行。实时上报可以在发布后,快速了解应用质量,适配最新iOS、Android官方操作系统,鹅厂工程师都在用,快来加入我们吧!