##SiriKit 有关介绍

引言

  • 在6月14日凌晨的WWDC2016大会上,苹果提出iOS10是一次里程碑并且推出了十个新特性,homekit、messageapp等等,大部分是基于iPhone原生应用的更新。其中最大的亮点之一是Siri的接口开放,在iOS10中提供了SiriKit框架在用户使用Siri的时候生成INExtension对象来告知我们的应用,我们可以通过SiriKit提供的API展示给用户更多的内容。
  • Siri通过语言处理系统对用户发出的对话请求进行解析之后生成一个用来描述对话内容的Intents事件,然后通过SiriKit框架分发给集成框架的应用程序以此来获取应用的内容,比如通过文字匹配查找应用聊天记录、聊天对象等功能,此外还支持为用户使用苹果地图时提供应用内置服务等功能。

SiriKit六类服务

sirikit 服务 对应的INintent
语音和视频通话 VoIP calling INStartVideoCallIntent、INStartAudioCallIntent
发送消息 Messaging INSendMessageIntent
收款或者付款 Payments INSendPaymentIntent、INRequestPaymentIntent
图片搜索 Photo search INSearchForPhotosIntent
管理锻炼 Workouts INEndWorkoutIntent、INPauseWorkoutIntent 、INStartWorkoutIntent 、 INResumeWorkoutIntent 、INCancelWorkoutIntent
行程预约 Ride booking INRequestRideIntent、INGetRideStatusIntent、 INListRideOptionsIntent、 INGetRideStatusIntent

更加详细的说明参见Intents Domains
也就是说当我们使用sirikit的时候,可以使用以上列表对应的六种服务,比如说你的应用是联系人可以发送消息,这时候你就可以使用INSendMessageIntent服务,在锁屏或者主屏幕唤起siri,然后比方说说出“嘿,siri,在xxx应用上发送一条消息给剑剑”,然后siri就能响应并同时提供回调给你的应用siri extension。具体的流程我们会在下一节举例说明。

Siri执行流程

  • 示例流程图
siri1.png
siri2.png
  • 获取词汇逻辑


    siri_cihui.png

    从词汇中可以看到intent(暂且翻译成意图?)对应着siri给我们的响应,这是app通过处理intent对应的reslove,confirm,handle来做相关响应。

intents

1.intents说明

  • Action to be performed 定义将要响应的动作,即reslove,confirm,handle
  • Zero-to-many parameters 意图会有对应的参数来响应某些事件
  • Classified into a domain 意图划分的种类

Siri通过Intents extension的扩展方式和我们的应用进行交互,其中INExtension扮演着Intents extension扩展中直接协同Siri共同响应用户的角色。当我们实现了Intents extension扩展并产生了一个Siri请求事件时,Intents事件的处理过程分Resolve、Confirm和Handle三个步骤。

2.LifeCycle for an intent

一个intent的完整周期如下图:

siri_life.png
  • Resolve阶段。在Siri获取用户的语音输入之后,生成一个INIntent对象,将语音中的关键信息提取出来并且填充对应的属性,该对象会传递给我们设置好的INExtension子类对象进行处理,根据子类遵循的不同protocol来选择不同的解决方案。在上一个阶段通过handler(for intent:)返回了处理intent的对象,此阶段会依次调用confirm打头的实例方法来判断Siri填充的信息是否完成。
    resolve阶段用户大致分为以下说明阶段:

助SIri明白用户的含义
影响Siri的行为

提供resolution response
successWithResolvedPerson:成功找到匹配的人
disambiguationWithPeopleToDisambiguate:还需要挑选
confirmationRequiredWithPersonToConfirm:还需要确认下
needMoreDetailsForPerson:还需要更具体的信息,需要Siri进行询问
unsupportedWithReason:无法使用指定值
needsValue:需要某些必需值
notRequired:应用并没有要求某些值

  • Confirm阶段。确认信息。检查必要的状态等。Siri进行最后的处理阶段,生成答复对象,并且向此intent对象确认处理结果。

告诉Siri预期结果
检查必要的状态
提供Intent response
Siri提供必要的确认提示,参考如下连图例

siri3_confirm.png
siri_confirm2.png
  • Handle阶段:在Confirm方法执行完成之后,然后显示结果给用户看

    执行请求操作
    提供有关结果足够精确的信息
    如果结果耗时的话还可提供loading

siri_handle.png

实现一个Siri Kit应用

  • 升级到Xcode8,一台升级到iOS10的测试设备
  • Intents extension : resolve、confirm、handle流程
    新建extension如下图:


    siri_ex2.png

通常SiriUI也会配置一起创建,入后配置info.plist文件


siri_info2.png

上图中IntentsSupported是指你的扩展支持的intent类型,如果你的代码想支持某种intent必须在这里配置。
IntentsRestrictedWhileLocked是指在锁屏状态下能用siri唤起的intent,如果你想在锁屏下能唤起siri的扩展功能必须配置。


siri_info.png

创建之后,查看plist文件
  • 1.增加xxxintent
  • 2.NSExtensionPrincipalClass,这里必须在plist声明,它是INExtension的子类,INIntentHandleProviding,handleForIntent,handleClass must conform to specific intent handling protocol等,详细说明参见Intents Domains
    主项目plist 增加NSSiriUsageDescription 这个是请求Siri权限时提示的文案
    使用Siri时,用户必须说出App的名字,也就是Bundle display name
sendmessage.png

以发送消息为例:当siri第一次确认的时候,需要应用授权,授权代码和提示如下图:

siri_auth.png

具体intent的声明周期代码参考苹果官方demo,代码示例如下:

// MARK: 1. Resolve
    func resolveRecipients(forSendMessage intent: INSendMessageIntent, with completion: ([INPersonResolutionResult]) -> Swift.Void) {
        
        
        if let recipients = intent.recipients {
            var resolutionResults = [INPersonResolutionResult]()
            
            for recipient in recipients {
                let matchingContacts = UCAddressBookManager().contacts(matchingName: recipient.displayName)
                
                switch matchingContacts.count {
                    case 2 ... Int.max:
                        // We need Siri's help to ask user to pick one from the matches.
                        let disambiguationOptions: [INPerson] = matchingContacts.map { contact in
                            return contact.inPerson()
                        }

                        resolutionResults += [INPersonResolutionResult.disambiguation(with: disambiguationOptions)]
                        
                    case 1:
                        let recipientMatched = matchingContacts[0].inPerson()
                        resolutionResults += [INPersonResolutionResult.success(with: recipientMatched)]
                        
                    case 0:
                        resolutionResults += [INPersonResolutionResult.unsupported(with: INIntentResolutionResultUnsupportedReason.none)]
                    
                    default:
                        break
                }
            }
            
            completion(resolutionResults)
            
        } else {
            // No recipients are provided. We need to prompt for a value.
            completion([INPersonResolutionResult.needsValue()])
        }
    }
        
    func resolveContent(forSendMessage intent: INSendMessageIntent, with completion: (INStringResolutionResult) -> Swift.Void) {
        if let text = intent.content where !text.isEmpty {
            completion(INStringResolutionResult.success(with: text))
        }
        else {
            completion(INStringResolutionResult.needsValue())
        }
    }
    
    // MARK: 2. Confirm
    func confirm(sendMessage intent: INSendMessageIntent, completion: (INSendMessageIntentResponse) -> Swift.Void) {
        
        if UCAccount.shared().hasValidAuthentication {
            completion(INSendMessageIntentResponse.init(code: INSendMessageIntentResponseCode.success, userActivity: nil))
        }
        else {
            // Creating our own user activity to include error information.
            let userActivity = NSUserActivity.init(activityType: String(INSendMessageIntent))
            userActivity.userInfo = [NSString(string: "error"):NSString(string: "UserLoggedOut")]
            
            completion(INSendMessageIntentResponse.init(code: INSendMessageIntentResponseCode.failureRequiringAppLaunch, userActivity: userActivity))
        }
    }
    
    // MARK: 3. Handle
    func handle(sendMessage intent: INSendMessageIntent, completion: (INSendMessageIntentResponse) -> Swift.Void) {
        if intent.recipients != nil && intent.content != nil {
            // Send the message.
            let success = UCAccount.shared().sendMessage(intent.content, toRecipients: intent.recipients)
            completion(INSendMessageIntentResponse.init(code: success ? .success : .failure, userActivity: nil))
        }
        else {
            completion(INSendMessageIntentResponse.init(code: INSendMessageIntentResponseCode.failure, userActivity: nil))
        }
    }

  • Intents UI extension 提供界面自定义等内容
    通常确认界面的UI苹果会提供默认的样式,默认的样式如下图:
style_default.png

但是如果你想自定义UI,如下图所示,你就必须配置Intents UI extension,在MainInterface.storyboard配置相关UI,然后在对应的控制器中配置config函数。

style_custom.png

参考configs函数如下:

func configure(with interaction: INInteraction!, context: INUIHostedViewContext, completion: ((CGSize) -> Void)!) {
        var size: CGSize
        
        // Check if the interaction describes a SendMessageIntent.
        if interaction.representsSendMessageIntent {
            // If it is, let's set up a view controller.
            let chatViewController = UCChatViewController()
            chatViewController.messageContent = interaction.messageContent

            let contact = UCContact()
            contact.name = interaction.recipientName
            chatViewController.recipient = contact
            
            switch interaction.intentHandlingStatus {
                case INIntentHandlingStatus.unspecified, INIntentHandlingStatus.inProgress,INIntentHandlingStatus.ready:
                    chatViewController.isSent = false
                case INIntentHandlingStatus.done:
                    chatViewController.isSent = true
            }
            
            present(chatViewController, animated: false, completion: nil)
            
            size = desiredSize
        }
        else {
            // Otherwise, we'll tell the host to draw us at zero size.
            size = CGSize.zero
        }
        
        completion(size)
    }

  • Embedded frameworks
    由于你的程序是extension,因此你的siri扩展可能会和你的应用有数据共享,而且可能会有同样的逻辑代码,因此apple建议相关业务的逻辑代码可用framwork的形式,这样扩展和宿主app都可以使用。

参考

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

推荐阅读更多精彩内容

  • 关于SiriKit 在6月14日凌晨的WWDC2016大会上,苹果提出iOS10是一次里程碑并且推出了十个新特性,...
    sindri的小巢阅读 22,290评论 40 79
  • 概览 最新的WWDC2016大会上,苹果提出iOS10并推出了十个新特性,homekit、messageapp等等...
    cuagain阅读 2,134评论 0 5
  • 介绍SiriKit SiriKit是让你的内容通过Siri展示的一个框架库。当用户向Siri请求特别类型的服务时,...
    孢子菌阅读 4,117评论 1 6
  • 在这里放出原文链接地址 Part 3.1: 分析与操作 Intents Intents Extension 的的入...
    李国安阅读 1,244评论 0 4
  • 一、SiriKit介绍 Siri是一款苹果 iOS 系统提供的智能语音助手软件,它的全名是 Speech Inte...
    火星抄手阅读 5,391评论 15 19