【转】玩转iOS开发:iOS 10 新特性《Siri Kit》-- 不错!(用“测试”发信息给张三)
原文网址:玩转iOS开发:iOS 10 新特性《Siri Kit》 – 掘金 (juejin.cn)
文章分享至我的个人技术博客: https://cainluo.github.io/14977885999456.html
Siri
众所周知Siri
是苹果爸爸内置在iOS
系统的一个语音助手, 自从在2011年的iPhone 4s
问世之后, Siri
就一直受关注.
但好景不长, 随着Siri
的功能和权限太弱了, 慢慢就被人遗忘, 起码我身边用iPhone
的小伙伴都会把Siri
给关掉, 按照他们的说法就是可以省电…我也是醉了.
几年过去后, Siri
终于迎接来了春天, 随着iOS 10
的推出, 终于给开发者们开放了Siri Kit
, 也开放了Siri Intents Extension
, 国内用的最快的App
依然还是BAT
巨头的产品, 比如QQ
.
这里的工程是Objective-C
版本, 想看Swift
版本的, 可以到这里去查看.
Siri的服务类型
这里我简单的举一下Siri
目前支持的一些种类, 更加详细的文档请看官方文档.
Siri服务类型 | Intent种类 |
---|---|
VoIP语音 – VoIP calling | INStartVideoCallIntent、INStartAudioCallIntent |
消息 – Messaging | INSendMessageIntent |
支付 – Payments | INSendPaymentIntent、INRequestPaymentIntent |
图片 – Photos | INSearchForPhotosIntent |
健身 – Workouts | INEndWorkoutIntent、INPauseWorkoutIntent 、INStartWorkoutIntent 、 INResumeWorkoutIntent 、INCancelWorkoutIntent |
骑行预约 – Ride booking | INRequestRideIntent、INGetRideStatusIntent、 INListRideOptionsIntent、 INGetRideStatusIntent |
汽车状态 – Car commands | INSetCarLockStatusIntent、INGetCarPowerLevelStatusIntent、INActivateCarSignalIntent |
车载系统 – CarPlay | INSetAudioSourceInCarIntent、INSetClimateSettingsInCarIntent |
预定餐厅 – Restaurant reservations | INBookRestaurantReservationIntent |
New Project
创建新工程的项目这里我就忽略了, 直接来看添加Siri Intents Extension
:
这里注意一下, 我们要把Include UI Extension
也要勾上, 但这个东西会专门开一篇文章去讲解.
创建好之后, 我们可以看到Siri Intents Extension
和之前我们遇到的Extension
不太一样:
还有就是, 我们打开Siri Intents Extension
的Info.plist
文件看到IntentsSupported
和IntentsRestrictedWhileLocked
, 那有什么用呢?
-
IntentsSupported: 我们项目需要支持的
Siri Intents
就放到这里, 比如我们在工程里看到的INSendMessageIntent
,INSearchForMessagesIntent
,INSetMessageAttributeIntent
. -
IntentsRestrictedWhileLocked: 在锁屏状态下需要锁定的
Siri Intents
就放到这里, 比如我们在工程里看到的INSendMessageIntent
.
SiriKit的流程
关于SiriKit
的流程这里我就拷贝一下官方的说法:
Siri
和Maps
通过Intents extension
的扩展方式和我们的应用进行交互,其中,类型为INExtension
的对象扮演着Intents extension
扩展中直接协同Siri
对象共同响应用户请求的关键角色。当我们实现了Intents extension
扩展并产生了一个Siri
请求事件时,一个典型的Intent
事件的处理过程中总共有这三个步骤Resolve
、Confirm
和Handle
:
Resolve
阶段。在Siri
获取到用户的语音输入之后,生成一个INIntent
对象,将语音中的关键信息提取出来并且填充对应的属性。这个对象在稍后会传递给我们设置好的INExtension
子类对象进行处理,根据子类遵循的不同服务protocol
来选择不同的解决方案。Confirm
阶段。在上一个阶段通过handler(for intent:)
返回了处理intent
的对象,此阶段会依次调用confirm
打头的实例方法来判断Siri
填充的信息是否完成。匹配的判断结果包括Exactly one match
、Two or more matches
以及No match
三种情况。这个过程中可以让Siri
向用户征求更具体的参数信息。- 在
confirm
方法执行完成之后,Siri
进行最后的处理阶段,生成答复对象,并且向此intent
对象确认处理结果然后执显示结果给用户看。
交互名单
这里我们首先要创建一个名单, 用来模拟一下发送消息的场景:
这里还有一个NSString
的类别, 用来转换拼音的:
精确匹配和模糊匹配
回到我们的IntentHandler.m
文件, 这里我们要开始写代码了, 我们需要些一个精确的用户名称匹配和一个模糊的用户名称匹配:
// 遍历待匹配选项
for (INPerson *recipient in recipients) {
// Implement your contact matching logic here to create an array of matching contacts
NSMutableArray<INPerson *> *matchingContacts = [NSMutableArray array];
// 待匹配的名称
NSString *recipientName = recipient.displayName;
NSString *recipientNamePinYin = [recipientName cl_PinYin];
// 精确的匹配到列表里的用户
UserList *user = [UserList checkUserWithName:recipientName];
if (user) {
NSLog(@"匹配到精确用户:%@", user);
// 创建一个匹配成功的用户
INPersonHandle *personHandle = [[INPersonHandle alloc] initWithValue:user.userAddress
type:INPersonHandleTypeEmailAddress];
INImage *iconImage = [INImage imageNamed:user.userIcon];
INPerson *person = [[INPerson alloc] initWithPersonHandle:personHandle
nameComponents:nil
displayName:recipientName
image:iconImage
contactIdentifier:nil
customIdentifier:nil
aliases:nil
suggestionType:INPersonSuggestionTypeSocialProfile];
// 把匹配成功的用户记录下来
[matchingContacts addObject:person];
}
// 如果没有精确匹配到用户, 则用模糊匹配
if (matchingContacts.count == 0) {
NSLog(@"没有匹配到精确用户:%@", user);
for (UserList *user in [UserList userList]) {
// 匹配用户的名称
NSString *userName = user.userName;
NSString *userNamePinYin = [userName cl_PinYin];
if ([recipientName containsString:userName] || [recipientNamePinYin containsString:userNamePinYin]) {
// 创建一个匹配成功的用户
INPersonHandle *personHandle = [[INPersonHandle alloc] initWithValue:user.userAddress
type:INPersonHandleTypeEmailAddress];
INImage *iconImage = [INImage imageNamed:user.userIcon];
INPerson *person = [[INPerson alloc] initWithPersonHandle:personHandle
nameComponents:nil
displayName:userName
image:iconImage
contactIdentifier:nil
customIdentifier:nil
aliases:nil
suggestionType:INPersonSuggestionTypeSocialProfile];
// 记录匹配的用户
[matchingContacts addObject:person];
}
}
}
复制代码
注意
注意一下, 虽然我们代码写好了, 但我们还是需要看看工程里有没有添加-ObjC
还有就是Siri Intents Extension
和Siri Intents Extension UI
里有没有链接好NSString+PinYin.m
和UserList.m
:
不然就会发生"_OBJC_CLASS_$_UserList", referenced from:
错误了.
在运行之前一定要到设置 -> Siri -> 开启Siri
才可以使用, 这里我是用模拟器, 所以没法试着发邮件出去:
但是发消息还是ok
得, 效果:
总结
最后我们来看看额外的一篇文章, 就是企鹅公司是肿么给QQ适配SiriKit
的一些思路QQ适配 SiriKit.
工程地址
项目地址: https://github.com/CainRun/iOS-10-Characteristic/tree/master/9.Siri%20Intents
链接:https://juejin.cn/post/6844903481942376455
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。