iOS12 Siri Shortcuts(一)

INShortcut

这是Shortcut开发中要实现的核心class,我们看下这个类所提供的api:

API_AVAILABLE(ios(12.0), watchos(5.0)) API_UNAVAILABLE(tvos)    API_UNAVAILABLE(macosx)
@interface INShortcut : NSObject <NSSecureCoding, NSCopying>

/*!
 @abstract The intent that will be performed when this shortcut is invoked.
 @discussion Is @c nil if the shortcut was created with a @c NSUserActivity.
 */
@property (readonly, copy, nullable, NS_NONATOMIC_IOSONLY) INIntent *intent;

/*!
 @abstract The user activity that will be performed when this shortcut is invoked.
 @discussion Is @c nil if the shortcut was created with an @c INIntent.
 */
@property (readonly, strong, nullable, NS_NONATOMIC_IOSONLY) NSUserActivity *userActivity;

/*!
 @note Must be initilaized with either an intent or user activity, using those initializers.
 */
+ (instancetype)new NS_UNAVAILABLE;

/*!
 @note Must be initilaized with either an intent or user activity, using those initializers.
 */
- (instancetype)init NS_UNAVAILABLE;

/*!
 @abstract Creates a shortcut with the given intent.
 @param intent Must have a title and have valid shortcut types.
 @return Will return @c nil (and log an error) if the intent isn't valid.
 */
- (nullable instancetype)initWithIntent:(INIntent *)intent;

/*!
 @abstract Creates a shortcut with the given user activity.
 */
- (instancetype)initWithUserActivity:(NSUserActivity *)userActivity;

@end

INShortcut提供了两种模型,可以通过Siri和APP中进行接收和传递相关消息。

image.png

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

NSUserActivity使用方法:

先在项目的 plist 文件里定义 属性为 Array 的 NSUserActivityTypes,为其添加对应的属性值,比如:"com.xxxx.xxxx-sports"

然后在需要弹出添加捷径的页面试下下放代码即可:

- (void)gotoAddCustomVoiceShortcutView {
    NSUserActivity *activity = [self donateSportActivity];
    INShortcut *shortcut = [[INShortcut alloc] initWithUserActivity:activity];
    INUIAddVoiceShortcutViewController *vc = [[INUIAddVoiceShortcutViewController alloc] initWithShortcut:shortcut];
    vc.delegate = self;
    [self presentViewController:vc animated:YES completion:^{
    
    }];
}

//此方法返回一个 NSUserActivity 对象。
- (NSUserActivity *)donateSportActivity {
    NSUserActivity *checkInActivity = [[NSUserActivity alloc] initWithActivityType:@"com.xxxx.xxxxxx"];
    checkInActivity.eligibleForSearch = YES;
    if (@available(iOS 12.0, *)) {
        checkInActivity.eligibleForPrediction = YES;
        checkInActivity.suggestedInvocationPhrase = @"我回家了";//搜索的关键字
    }
    checkInActivity.title = @"执行场景";
    checkInActivity.contentDescription = @"开客厅灯,关窗帘,语音播报今天的新闻";
    return checkInActivity;
}

效果如下:


image.png

然后实现INUIAddVoiceShortcutViewController的两个delegate方法,分别处理取消和完成两个事件

#pragma mark - INUIAddVoiceShortcutViewControllerDelegate
- (void)addVoiceShortcutViewControllerDidCancel:(INUIAddVoiceShortcutViewController *)controller  API_AVAILABLE(ios(12.0)){
    [controller dismissViewControllerAnimated:YES completion:nil];
}

- (void)addVoiceShortcutViewController:(INUIAddVoiceShortcutViewController *)controller didFinishWithVoiceShortcut:(INVoiceShortcut *)voiceShortcut error:(NSError *)error  API_AVAILABLE(ios(12.0)){
   // 处理业务逻辑
    [controller dismissViewControllerAnimated:YES completion:nil];
}

PS:如果是修改Siri指令,直接把目标 vc 换成 INUIEditVoiceShortcutViewController 即可。

当然这里有还有一个问题,如何判断用户是否已经添加了语音短语,从而确定去选择 add or edit ?
Intent早已为我们准备好该方法,拿到结果后,遍历判断就好。
需要注意的是,该方法是不在主线程中执行,所以完成后,如果需要更新UI,请手动回到主线程。

[[INVoiceShortcutCenter sharedCenter] getAllVoiceShortcutsWithCompletion:^(NSArray<INVoiceShortcut *> * _Nullable voiceShortcuts, NSError * _Nullable error) {

 }];

接着在appDelegate里面去实现下面方法,用来处理用户通过Siri短语或者系统只能提示启动我们APP后的事件处理:

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{
   if (@available(iOS 12.0, *)) {
      if([userActivity.interaction.intent isKindOfClass:[LHSceneIntent class]]){
          LHLogInfo(@"*** shortCut 进入APP");
      } else {
          if ([userActivity.activityType isEqualToString: @"com.xxxx.xxxxx"])  {
              LHLogInfo(@"*** shortCut 进入APP");
          }
      }
  } else {
      // Fallback on earlier versions
  }
    return YES;
}

Siri ShortCuts 还有一个 Extension 的功能,可以在Shortcut 里面添加APP的一些操作,或者通过Siri界面直接执行一些操作(这才是iOS12 捷径真正方便强大的功能)。 我们下篇再讲

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

推荐阅读更多精彩内容