iOS开发-Siri预研

Siri介绍

Siri是一款苹果 iOS 系统提供的智能语音助手软件,它的全名是Speech Interpretation and Recognition Interface。在WWDC 2016上,苹果开放了Siri的 API,开发者们可以利用SiriKit将自己的服务提供给用户。

支持 iOS 10.0+;

官方文档:https://developer.apple.com/documentation/sirikit

以下内容均是对官方文档的解析!


概念概览

Domain - 被苹果划分的不同业务领域,每个领域中可以执行不同的任务

Intent - 领域中的任务或意图指令


Domains

VoIP Calling - 语音通信相关,如微信、Facebook Messager、Line等;

Payments - 适用于支付类应用,如PayPal、支付宝等;

Photo - 与图库相关应用,如Instagram等;

Workouts - 运动健康类应用,如Strava、NikeRun、野兽骑行等;

Ride booking - 适用于出行类应用,如Uber、滴滴打车等;

CarPlay(automotive vendors only)- 车载及自动驾驶相关,尚不明晰

Restarurant reservations(Requires addtional support from Apple) - 酒店服务类,具体需求上不明晰


Intents

VoIP Calling

    Start an audio call -开始语音通话

    Start a video call - 开始视频通话

    Search the user’s call history -搜寻通话历史

Messaging

    Send a message

    Search for messages

    Set attributes on a message

Photos

    Search for photos

    Play a photo slideshow

Payments

    Send a payment to another user

    Request a payment from another user

Workouts

    Start a workout

    Pause a workout

    Resume a workout

    End a workout

    Cancel a workout

Ride Booking

    Get a list of available rides (Maps only)

    Book a ride

    Get the status of a booked ride

CarPlay

    Change the audio source

    Change the climate control settings

    Change the defroster settings

    Saving vehicle settings to a profile

    Restoring vehicle settings from a profile

    Change the seat temperature

    Change the radio station

Restaurant Reservations

    Get the user’s current restaurant reservations

    Get information about the user to associate with a booking.

    Get default values to use when requesting reservation times.

    Get the reservation times that are currently available.

    Book a reservation for the user.


简单来说:

开发功能基本上就是在苹果提供的这些领域(Domain)上,在App开发中需要开发哪种领域的功能,就要在对应的plist文件中添加对应的Intent支持;

当然SiriKit不是万能的,语义的处理流程要按照苹果的套路来(应用领域,意图),界面UI也套路来,不能调用App内部页面。

那什么是Intent呢?

了解Intent,首先要清楚SiriKit的外部工作流程:

1)、Siri完成语音识别和语义分析;

2)、会根据你词汇中的关键词识别出你属于上述领域(Domain)中的哪一种;

3)、然后将结构化语音分析结果打包成一个某个领域(Domain)的意图(Intent);

4)、接着交给支持这个意图(Intent)的第三方应用,第三方应用被启动,从传入的Intent中获取相应的信息,完成操作。

整个宏观的流程如下图:


例如,上图演示中提到了的例句 “用演示发消息给小明",

领域 (Domain):Messaging

意图 (Intent):Send a message (INSendMessageIntent)

意图参数 (Intent Parameter)

收件人(recipients):小明

消息内容(content):空

备注:(appname:演示。如果没有消息内容,这时就会涉及到Sikit的API中提供的处理机制,这个机制会调Siri反问你要发送什么内容,这个就涉及到下文提到的SiriKit相关功能和处理流程,会有不同的扩展和类在处理这个问题)


项目集成

1.先创建对应的target:


根据需求确认是否需要 UI Extension ,该target类似于富文本推送;

生成结果:

2.定义需要支持的Intent类型:


支持类型的具体对应内容可参考官方文档

IntentsRestrictedWhileLocked是可选项,用来控制锁屏状态下,对不同命令的响应行为。

3.添加对主应用Siri权限支持

在主应用Info.plist文件中添加NSSiriUsageDescription Key,该key用来标记应用与Extension所沟通的数据类型,用于告知用户,你的应用为何要支持Siri的描述信息,比如Workout类应用,我可以这么写:“健身锻炼的信息会发送到Siri,更快捷的记录健身数据”

仅仅添加NSSiriUsageDescription这个Key到Info.plist文件中是不够的,当应用第一次启动时,我们需要用户打开应用的Siri支持权限,默认情况下,这个权限是关闭的,所以,需要我们通过调用INPreferences的类方法equestSiriAuthorization: 来通知用户打开Siri权限支持。

4.一个标准的意图语音被Siri识别之后,SiriKit会先进入一个继承于INExtension的指定意图流程入口(NSExtensionPrincipalClass)类IntentHandler.m(默认类)。下面在这个相关类会处理整个流程:

意图的生命周期如下图文描述:

一个典型的Intent事件的处理过程中有这三个步骤Resolve、Confirm和Handle

Resolve阶段。在Siri获取到用户的语音输入之后,生成一个INIntent对象,将语音中的关键信息提取出来并且填充对应的属性。这个对象在稍后会传递给我们设置好的INExtension子类对象进行处理,根据子类遵循的不同协议来选择不同的解决方案。

Confirm阶段。在上一个阶段通过handlerForIntent:(INIntent *)返回了处理Intent的对象,此阶段会依次调用confirm打头的实例方法来判断Siri填充的信息是否完成。匹配的判断结果包括Exactly one match、Two or more matches以及No match三种情况。这个过程中可以让Siri向用户征求更具体的参数信息。

Handle阶段。在confirm方法执行完成之后,Siri进行最后的处理阶段,生成答复对象,并且向此Intent对象确认处理结果然后执显示结果给用户看。


4.发消息INSendMessageIntent的意图对象

具体在各个阶段的方法里怎么代码实现,主要是要理解INSendMessageIntent的对象属性,通过解析对象,可以在各个阶段用获取到的对象进行相关程序逻辑编码。如:

对象名称类型备注

通过流程方法里获取到INSendMessageIntent对象进行解析,匹配,处理,这个过程还涉及到返回的处理。每一个解析方法都需要得到一个INIntentResolutionResult类型的实例,用来保存校验结果。

INIntentResolutionResult及其子类有不同的构造方法生成不同类型的结果,用来指定和Siri的交互。

| 值类型INIntentResolutionResult| 说明|

| --- | --- |--- |

|+ (instancetype)needsValue;| 需要一个值,Siri会提示用户给一个值|

|+ (instancetype)notRequired;| 不是必要的,是否给值都会过这个resolve|

|+ (instancetype)unsupported;| 不支持的,Siri会提示用户这个值不被支持|

|+(instancetype)successWithResolvedValue:(BOOL)resolvedValue;| 成功解析|

|+(instancetype)confirmationRequiredWithValueToConfirm:(nullable NSNumber *)valueToConfirm;| Siri提示用户确认当前是否是一个bool值|

当一个intent的所有参数都成功解析了,处理程序就会向用户询问是否确认这个intent的细节,并且提供一个建议响应。当所有参数被成功解析后,或者在不要求所有参数进行解析,那么就认为是解析成功。

在确认期间,就可以执行所有的intent参数的附加验证,以确保你可以使用该信息来执行所请求的服务。如果之前的解析函数是单元测试,那么这个确认函数就是集成测试,保证所有输入参数正确。

最后一个处理intent的阶段,就是执行与这个intent相关的动作。在-handleSendPayment:completion函数中做相应业务逻辑,需要注意的是你在Extension中做的修改也应当反应到App主程序当中,所以需要提供任务的数据给到App。SiriKit提供了一个包含intent细节(INIntent、INIntentResponse)的InInteraction对象,你可以使用userActivityInstance.interaction得到它,在App启动时调用

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler

函数处理来自Extension的数据。

5.根据流程方法处理之后,与主程序通信方式

轻量级通信可采用这个办法:

1)、在handling阶段在NSUserActivity存储相应的信息,字典或字符串都行(如上handling阶段代码)。

2)、在AppDelegate,获取NSUserActivity所存储的信息。

3)、发送通知给所需要的地方。

4)、接收到通知后对主程序进行相应操作。

在AppDelegate中处理SiriKit的Intent可以参考官方文档

//AppDelegate.m- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { return NO;}- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivityrestorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler { if ([userActivity.interaction.intent isKindOfClass:[INSendMessageIntent class]]) { INSendMessageIntent *intent = (INSendMessageIntent *)(userActivity.interaction.intent); NSLog(@"%@",[[intent.recipients lastObject] displayName]); } return YES;}

6.自定义界面(Intent UI Extension)

运用SiriKit开发相关功能,UI是依赖于Intent UI Extension,SiriKit并不能从系统层面调用App内部UI,只能调用打开App和SirKit自定义UI。


系统创建了ViewController,加载视图,调用viewDidLoad方法并且调用了INUIHostedViewControlling协议的configureWithInteraction:context:completion:方法,传递了一个交互对象,用于配置界面。 当配置完成后,ViewController就会展示在Siri或者Maps应用界面的空白部分。这时会调用viewWillAppear/viewDidAppear方法。

当视图消失时,也会调用生命周期的viewWillDisappear/viewDidDisappear方法。

类似于富文本推送的 UI 界面构造方式。

关于控制器的使用,苹果给出了几点注意事项:

1.切换子控制器来展示不同类型的内容。 你的Intents UI扩展只有一个主视图控制器,如果你想为不同的Intents展示不同的内容,你需要使用不同的视图。可以在configureWithInteraction:context:completion:这个方法里面,根据提供的intentObject来创建不同的子视图。

2.在你的视图控制器可用的期间,动态调整内容。 在viewDidAppear:方法里面才开始启动动画,在viewWillDisappear: 方法里面要结束动画。

3.尽快的配置好你的视图控制器,这样Siri才能更快的展示它。 你的视图控制器也许不会在屏幕上停留太久,所以尽量利用本地资源以及提供的INInteraction对象来配置你的设置。如果你需要从服务器拉取更多的信息,请异步完成,并在稍后再更新你的界面。

4.请不要在界面里面展示广告。你可以展示你自己的品牌信息,但是你不能够加入其它广告。


参考文档:

https://www.jianshu.com/p/0881bb0ff538

https://www.jianshu.com/p/eb15faeb4a66

https://www.jianshu.com/p/d0e157627f3a

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容