阅读 2133

iOS12 Siri Shortcuts详解

本文介绍了使用OC如何构建带有Shortcuts的项目.
转载请注明出处:juejin.im/post/5b51b4…

Shortcuts其初衷是为了让用户通过Siri使用一句简短的话来实现一些复杂操作.举个栗子就像是你给了Siri一个眼神,然后Siri就知道你要干嘛了.

创建Shortcuts的基本流程


1.声明Shortcuts(Define Shortcut)
2.配置Shortcuts(Donate Shortcut)
3.接收Shortcuts的回调(Handle Shortcut)

Shortcuts APIs


Shortcuts提供了2种模型,用于在Siri中接收与传递相关信息.

下表列出了两种模型的推荐使用情况以及区别:

NSUserActivity Intents
需要打开app进行操作时使用 需要在Siri界面直接操作时使用
仅仅表示在Spotlight中的索引项目时 需要对操作添加自定义短语或自定义UI时
Siri建议的颗粒度较大 Siri会根据不同情况给出相对精确的建议

NSUserActivity使用方法:

1.在info.plist中添加NSUserActivityTypes

2.添加代码

    NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:@"com.js.sirishortcuts-activity-type"];
    userActivity.eligibleForSearch = YES;
    userActivity.title = @"这是标题";
    if (@available(iOS 12.0, *)) {
        userActivity.eligibleForPrediction = YES;// 新属性,赋值为 true 后可以暴露给 `SiriKit`
        userActivity.suggestedInvocationPhrase = @"打车回家";//搜索的关键字
    }
    CSSearchableItemAttributeSet * attributes = [[CSSearchableItemAttributeSet alloc] init];
    UIImage *icon = [UIImage imageNamed:@"main_icon_jinbi_layer_bao02"];
    attributes.thumbnailData = UIImagePNGRepresentation(icon);
    attributes.contentDescription = @"这是副标题";
    userActivity.contentAttributeSet = attributes;
    self.userActivity = userActivity;//self 为controller
复制代码

运行代码,在搜索页面即可看到:(请自动忽略app名称...)

3.在appdelegate中添加回调

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
    if ([userActivity.activityType isEqualToString: @"com.js.sirishortcuts-activity-type"]) {
        NSLog(@"enter");
    }
    return YES;
}
复制代码

至此,NSUserActivity添加完成~

Intents使用方法:

1.添加Intents文件
File -> New File,选择 SiriKit Intent Definition File

2.配置Instents文件

关于Intents在哪里生成代码的问题.
苹果官方推荐的使用方法是提取一个公共的framework,方便extension和target一起使用. 如果你已经有一个公共framework,那么建议你的代码生成在framework中. 否则.你需要在每一个需要使用的target中生成一遍代码. 添加方式如下图(此处使用的截图是官方给出的demo中的截图).

选好后编译即可生成对应代码.生成后的文件名为<IntentsName+Intents> 如IntentsName为GoHome,那么生成生成的文件名为GoHomeIntent.h(oc),文件名还可以直接看Intents文件的这里:

3.添加Intents Extension

添加Extension后会看到有三个文件:

修改info.plist如图.
新建一个GoHomeIntentHandler继承自NSObject,用于接收我们的自定义Instent,注意这里需要导入Intent生成的h文件.

#import <Foundation/Foundation.h>
#import "GoHomeIntent.h"

NS_ASSUME_NONNULL_BEGIN

@interface GoHomeIntentHandler : NSObject <GoHomeIntentHandling>

@end

NS_ASSUME_NONNULL_END
复制代码

在GoHomeIntentHandler.m中实现协议方法. Intent 的生命周期分为:(解析和纠错收件人和消息内容)Resolve - (确认用户的操作)Confirm - (将消息发送出去)Handle

@implementation GoHomeIntentHandler
- (void)confirmGoHome:(GoHomeIntent *)intent completion:(void (^)(GoHomeIntentResponse * _Nonnull))completion {
    NSLog(@"confirmGoHome");
}

- (void)handleGoHome:(nonnull GoHomeIntent *)intent completion:(nonnull void (^)(GoHomeIntentResponse * _Nonnull))completion {
    NSLog(@"handleGoHome");
    GoHomeIntentResponse *response = [GoHomeIntentResponse successIntentResponseWithTime:intent.time ?: @"" location:intent.location ?: @"" price:@""];
    completion(response);
}

@end
复制代码

在IntentHeader.m文件中,自定义用于接收的类

- (id)handlerForIntent:(INIntent *)intent {
    // This is the default implementation.  If you want different objects to handle different intents,
    // you can override this and return the handler you want for that particular intent.
    return [[GoHomeIntentHandler alloc] init];
    //return self;
}
复制代码

4.Donate Shortcuts

- (void)gotoAddCustomVoiceShortcutView {
    GoHomeIntent *intent = [[GoHomeIntent alloc] init];
    intent.location = @"朝阳门东路";
    intent.time = @"下午5:00";
    intent.suggestedInvocationPhrase = @"下午回家";//提示用户
    INUIAddVoiceShortcutViewController *vc = [[INUIAddVoiceShortcutViewController alloc] initWithShortcut:[[INShortcut alloc] initWithIntent:intent]];
    vc.delegate = self;
    [self presentViewController:vc animated:YES completion:^{
        ;
    }];
    
    //修改
    //    INUIEditVoiceShortcutViewController *vc = [[INUIEditVoiceShortcutViewController alloc] initWithVoiceShortcut:voiceShortcut];
//    vc.delegate = self;
//    [self presentViewController:vc animated:YES completion:^{
//        ;
//    }];

}
复制代码

运行添加即可看到Siri添加自定义短语的页面.点击红色按钮录音. 从下图中可以看出.我们之前输入的变量已经被之前instents中设置的模板转为对应的文案了.

删除 donate

1.NSUserActivity

[NSUserActivity deleteSavedUserActivitiesWithPersistentIdentifiers:@[@"com.js.sirishortcuts-activity-type"] completionHandler:^{
}];

[NSUserActivity deleteAllSavedUserActivitiesWithCompletionHandler:^{
}];
复制代码

2.Shortcuts

[INInteraction deleteInteractionsWithIdentifiers:@[@"ur id"] completion:^(NSError * _Nullable error) {
    ;
}];
[INInteraction deleteAllInteractionsWithCompletion:^(NSError * _Nullable error) {
    ;
}];
[INInteraction deleteInteractionsWithGroupIdentifier:@"ur group id" completion:^(NSError * _Nullable error) {
    ;
}];
复制代码

测试


为了便于调试,iOS12为我们提供了在锁屏界面和soptlight搜索界面显示上次Shortcuts命令的调试选项.不需要一遍一遍对Siri说指令了.
设置 -> 开发者-> SHORTCUTS TESTTING

此外.在调试extension时.还可以直接键入Siri指令

OTHER


Siri ShortCuts 的推荐逻辑

Siri会根据用户的使用习惯.在锁屏或者搜索页面给出推荐的选项.并且会根据你使用时间的增加和使用习惯的改变进行改变. 这里根据WWDC 211和其官方给出的demo举例

  • NSUserActivity
    如图,每天在相似的时间选择相似的选项,变量数为1,此时系统会根据次数较多的进行推荐.
    但是往往事件的变量不止一个.拿官方demo举例,汤的变量有商品名,数量,选择时滚动的距离等.

此时系统会保留相同项.得出相同项最多的一个结果.

  • Intens
    Intens在设置的时候会提供统一的模板来设置变量.
    将模型抽象出三种情况.每次统计会根据这三种情况综合分析.

综合分析后,选择相同项最多的结果:
可见.通过这种方式得出的结果比NSUserActivity的推荐结果会更加准确.

推荐的使用规则.

苹果建议我们使用如下的规则引导用户使用Siri ShortCuts:
1.保存我们对Siri ShortCuts的操作结果.使我们的操作与系统保存的结果一致.
2.避免使用时间戳等变量.
3.避免参数之间可能存在的隐式依赖关系. 另外如开篇所说.Siri ShortCuts的设计初衷是让用户使用简短的一个短语来减少复杂的操作.

初来乍到.难免有些错误.如果有任何疑问欢迎留言指正~

参考

WWDC 211
WWDC 214
WWDC 2018: Shortcuts 快速入门
iOS12 Siri ShortCuts 应用 (一)
WWDC 2018:初识Siri Shortcuts Apple Siri接入开发 (一)

关注下面的标签,发现更多相似文章
评论