Apple Siri接入开发 (一)

随着iOS10.0发布脚步的临近,作为开发者,相信很多人也和我一样,可以提前体验一些新系统的新功能,也更关注新版iOS系统带来的技术开发方面的新特性。

对新事物,尤其是软件开发新技术的好奇心驱使我最近尝试了一些iOS10.0推出的新特性的开发,其中就包括本次iOS系统更新开发的SiriKit接入。下面,我就详细讲述一下SiriKit接入的相关开发过程及注意事项,个人见解,如有错误,欢迎大家交流指正。

关于SiriKit

SiriKit是Apple历经4年时间,不断打磨优化,第一次开发给开发者的一份关于Siri功能的礼物。利用SiriKit,第三方开发者可以像一些系统应用一样,通过语音完成第三方应用希望完成的一些功能,比如用户可以直接通过语音直接告诉Siri打车、锻炼、寻找美食、寻找相册中的照片、甚至付给朋友AA的账单费用,以及控制家里智能家居等。

概念概览

  • Domain - 被苹果划分的不同业务领域,每个领域中可以执行不同的任务
  • Intent - 领域中的任务或意图指令

实现机制

和Android的语音接入Service类似,SiriKit中,将不同的类型的需求统一汇总为若干个Domain,然后在每个Domain中再次细分为不同的Intent。系统通过语音识别获取到的Domain信息以及Intent信息,下发到已注册的Domain中进行处理,然后用户解析处理不同的Intent,来实现自定义的操作。

SiriKit的接入方式和Watch OS的接入有相似之处,都是以Extension形式存在,该Extension会声明本应用所能处理的Domain内容及Intent种类,告知Siri该应用所能处理的功能范畴.这样,即便你的应用当前并没有打开或在后台运行,通过Siri也可以唤醒你的应用,处理相关逻辑。

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及Intents都有固定或相似的语法形式,为增加识别度,可以参考官网说明,按照说明中自然语言语法形式唤起相应的Siri功能,例如:”用XXX开始跑步“ 要比仅仅说 “XXX开始跑步”能更好的识别出应用XXX。

由于Siri所使用的识别技术及语言模型是在云端训练并完成数据解析,可能还有些不完善。在我们刚开始开发时,就遇到了这样的问题,中文普通话的有些Intent会有支持不完整的情况,导致语音识别不出来,无法完成语义解析,相关回调方法不被调用等问题,如有大家也遇到了类似问题,建议使用英文进行测试。

对于此问题,也已经向Apple Siri开发团队反应,相关训练任务已经在进行中,很惊喜的是,在之后的开发中,有些之前不支持的Intent语义识别也已经可以使用了。

开发流程

上面简述了SiriKit的一些背景知识及实现机制,下面简单介绍一下我在接入SiriKit时使用的开发流程.

开发环境

  • MacbookPro. OSX EI Capitan 10.11.6
  • xCode 8.0 beta6(8S201h)
  • iPhone6 iOS10.0 beta6
  • iTerms2, git, etc.

支持类型

对于向现有iOS应用中加入对Siri的支持有两种形式,一种是Intents Extension,另一种是Intents UI Extension,前者没有UI界面,类似一个后台逻辑处理服务,这项Extension是必选的。

而Siri UI Extensions是可选内容,用于展示一些确认信息等操作。经负责该功能的Apple SiriKit工程师确认,UI Siri Extensions的声明周期比较短,部分应用可根据实际需要采用,但Workout类应用目前试用范围较宅,本例中未采用。

接入步骤

本次接入SiriKit开发中,采用Workout类应用,此处Workout并不是Apple WatchOS 3.0中新增的Workout App, 而是指一类运动锻炼相关应用,例如,Strava, Nike Run一类。由于Apple SiriKit中限制了7类不同的Domain,如果需要接入其他类别的应用,如天气,支付等,可以参考官方接入指南进行相关开发。

Step1. 打开应用的Siri Capability

在Xcode8中,选中应用Target,选择Capability标签,打开Siri Capability打开,如图所示:


Apple Siri接入开发 (一)_第1张图片
201702072461357c303f4ab644135ea06285a.png

打开该属性后,工程文件的Entitlements文件会增加如下内容:


Apple Siri接入开发 (一)_第2张图片
201702071729357c303f4ab644135ea06285b.png

Step2: 创建支持Siri的Intents Extension

首先选中App工程,为该App添加对Siri的Intents Extension支持的Target,如图:


Apple Siri接入开发 (一)_第3张图片
201702075782857c303f4ab644135ea062857.png

选择Intents Extension


Apple Siri接入开发 (一)_第4张图片
201702076878357c303f4ab644135ea062858.png

命名并选择是否UI Extension,可根据自我业务需求确定,本例中,对UI Extension不进行支持。


Apple Siri接入开发 (一)_第5张图片
20170207372957c303f4ab644135ea062859.png

创建完成后,Siri Intents Extension的target会显示在Target列表中。

Step3: 定义所支持的Intent

该步骤相当于告诉Siri及iOS系统,本应用中所支持的Domain和Intents都有哪些,这样iOS系统及Siri就知道你的应用可以处理哪些请求,不能处理哪些请求。
打开Siri Intents Extension工程中的Info.plist文件,选中NSExtension,修改所支持的Intent类型,具体类型字符串可以查询开发文档,添加后的内容如下:


Apple Siri接入开发 (一)_第6张图片
201702076763357c30921ab644133ed0638de.png

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

Step4:添加对主应用Siri权限支持

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

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

Step5. 添加逻辑

OK,到此为止,我们已经把所有接入Siri Intents Extension的前期准备工作都已经完成,现在我们要进入正题,实现相应的逻辑处理代码编写工作。
修改IntentHandling.swift文件,根据需要,修改所需要实现的协议内容:

class  IntentHandler:INExtension,INStartWorkoutIntentHandling,INPauseWorkoutIntentHandling,INResumeWorkoutIntentHandling,INEndWorkoutIntentHandling{
    ...
}

OK,到此为止,我们已经把所有接入Siri Intents Extension的前期准备工作都已经完成,现在我们要进入正题,实现相应的逻辑处理代码编写工作。
修改IntentHandling.swift文件,根据需要,修改所需要实现的协议内容:

class IntentHandler:INExtension,INStartWorkoutIntentHandling
    ,INPauseWorkoutIntentHandling,INResumeWorkoutIntentHandling
    ,INEndWorkoutIntentHandling{
    ...
}

修改所需要实现的不同场景下的逻辑回调部分,调用所在iOS App的相关业务逻辑,满足产品需求,例如

开始锻炼

/*!
@briefhandlingmethod
@abstractExecutethetaskrepresentedbytheINStartWorkoutIntentthat
    'spassedin
@discussionThismethodiscalledtoactuallyexecutetheintent
    .Theappmustreturnaresponseforthisintent.
@paramstartWorkoutIntentTheinputintent
@paramcompletionTheresponsehandlingblocktakesaINStartWorkoutIn
    tentResponsecontainingthedetailsoftheresultofhavingexecutedthe
    intent
@seeINStartWorkoutIntentResponse
*/
public func handle(startWorkoutintent:INStartWorkoutIntent,completion
    :@escaping(INStartWorkoutIntentResponse)->Swift.Void){
    print("HereisStartworkoutcalledbySiri");
}

暂停锻炼

//MARK:-INPauseWorkoutIntentHandling
/*!
@briefhandlingmethod
@abstractExecutethetaskrepresentedbytheINPauseWorkoutIntentthat
    'spassedin
@discussionThismethodiscalledtoactuallyexecutetheintent
    .Theappmustreturnaresponseforthisintent.
@parampauseWorkoutIntentTheinputintent
@paramcompletionTheresponsehandlingblocktakesaINPauseWorkoutIn
    tentResponsecontainingthedetailsoftheresultofhavingexecutedthe
    intent
@seeINPauseWorkoutIntentResponse
*/
public func handle(pauseWorkoutintent:INPauseWorkoutIntent,completion
    :@escaping(INPauseWorkoutIntentResponse)->Swift.Void){
    print("HereisPauseworkoutcalledbySiri");
}

恢复锻炼

//MARK:-INResumeWorkoutIntentHandling
/*!
@briefhandlingmethod
@abstractExecutethetaskrepresentedbytheINResumeWorkoutIntenttha
    t'spassedin
@discussionThismethodiscalledtoactuallyexecutetheintent
    .Theappmustreturnaresponseforthisintent.
@paramresumeWorkoutIntentTheinputintent
@paramcompletionTheresponsehandlingblocktakesaINResumeWorkoutI
    ntentResponsecontainingthedetailsoftheresultofhavingexecutedth
    eintent
@seeINResumeWorkoutIntentResponse
*/
public func handle(resumeWorkoutintent:INResumeWorkoutIntent
    ,completion:@escaping(INResumeWorkoutIntentResponse)->Swift.Void){
    print("HereisResumeworkoutcalledbySiri");
}

结束锻炼

//MARK:-INEndWorkoutIntentHandling
/*!
@briefhandlingmethod
@abstractExecutethetaskrepresentedbytheINEndWorkoutIntentthat's
    passedin
@discussionThismethodiscalledtoactuallyexecutetheintent
    .Theappmustreturnaresponseforthisintent.
@paramendWorkoutIntentTheinputintent
@paramcompletionTheresponsehandlingblocktakesaINEndWorkoutInte
    ntResponsecontainingthedetailsoftheresultofhavingexecutedthei
    ntent
@seeINEndWorkoutIntentResponse
*/
public func handle(endWorkoutintent:INEndWorkoutIntent,completion
    :@escaping(INEndWorkoutIntentResponse)->Swift.Void){
    print("HereisEndworkoutcalledbySiri");
}

总结

以上就完成了所有接入SiriKit的工作,剩余的应用就是测试成果,此处有一些技巧,

  • 技巧一:由于SiriKit首次发布,有些语言支持尚不完善,建议使用英文进行测试,这样可以避开一些Intent在不同语言中支持不完整的问题。
  • 技巧二:iPhone6s及以后设备已经支持了通过“Hey, Siri”语音唤醒的特性,所以用iPhone6s可以方便的不用按住Home就可进行测试,很方便,对于iPhone6 & iPhone6P,插入数据线,连接电脑,也可以通过“Hey, Siri”唤醒,直接进行相应业务需求测试。

以上就是接入SiriKit的背景知识点以及基本流程,在接入过程中,与Apple SiriKit开发团队接触过程中,发现了若干问题,也收获了许多知识,在后续文章中,我会单独抽出一篇来与大家分享。文章中间如有错误之处,欢迎大家批评指正,共同成长。

Enjoy your Siri trip.

2017年2月

参考文献

  • Apple SiriKit Programming Guide

你可能感兴趣的:(Apple Siri接入开发 (一))