首页 > 代码库 > sirikit

sirikit

SiriKit 编程指南

 

SiriKit 介绍 Introduction to SiriKit

重要:本文档初步包含SiriKit API与SiriKit技术开发的信息。这些信息可能会有变更,根据这个文档实现的软件应该被测试在最后的操作系统中。

SiriKit 一个让你的内容可以通过Siri使用的新方式。它还将支持您的服务添加到地图应用中去。想要支持SiriKit使用Intents.framework和IntentsUI.framework实现一个或多个扩展,包含在你的iOS应用程序中。当用户通过Siri或地图请求特定类型的服务,系统将会使用你的扩展来提供这些服务。技术分享

只有当你的应用程序实现了下列服务类型之一,才能增加SiriKit支持:

  • 语音通话 Audio or video calling:打电话、发起视频电话、查通话记录

  • 信息 Messaging:发信息、搜索信息

  • 个人之间的付款 Payments: 向某人付款、向某人收款

  • 照片搜索 Searching photos :搜索照片、播放照片幻灯片

  • 健身 Workouts :开始健身、暂停健身、恢复健身、结束健身、取消健身

  • 打车 Ride booking:查看附近可用的车辆、订车、查看订单

注意:汽车厂商可能使用CarPlay意图来允许用户使用语音命令控制汽车。

每个类型的服务代表一个(domain)领域的功能,你可以支持,为每个(domain)领域定义一个或多个的(intents)意图对来支持。一个(intent)意图是一个代表用户意图的对象。Siri和地图创建意图对象以响应用户请求,填补任何指定的信息。例如,发送消息的意图可能包括消息的接收者和内容。你使用意图对象提供一个适当的响应和执行相关的任务。关于支持的领域更多信息和他们的所有意图。查看Intents Domains

意图和意图UI扩展 The Intents and Intents UI Extensions

Siri和地图通过两个不同类型的扩展与你的应用程序服务交互:

  • 一个意图Intents 扩展沟通你的app内容,Siri和地图,并执行与任何支持的意图有关的任务。
  • 一个Intents UI扩展在Siri或地图界面中,为您的内容提供了一个自定义的接口。这个扩展是可选的。

你必须提供一个意图扩展支持 SiriKit。你的意图扩展负责处理意图和用于提供信,Siri和地图可以用来与用户进行通信。提供一个意图UI( Intents UI)扩展是可选的,通过Siri和你的的APP交互是一种可以熟悉你的用户的方式例如,意图UI扩展可以展示品牌和其他应用程序特定的信息去强化APP提供响应的一些想法。

关于classs的使用实现你的意图扩展的更多信息,参考Intents Framework Reference. 实现Intents UI扩展的协议信息参考 Intents UI Framework Reference.

Siri的角色和地图应用

Siri 处理语言过程和语义分析,把用户的请求的口语转化为可操作的意图。 Siri的和地图应用管理所有的用户交互,并使用标准的系统界面显示结果给用户。你的作用主要是提供数据以显示。如果您的应用程序包括意图UI扩展,你也可以提供一个自定义界面,以补充默认的系统界面。

打车和餐馆预订主要由地图应用程序处理,但用户也可以使用Siri打车。你的意图扩展要以相同的方式处理来源于地图和Siri的请求。如果您自定义用户界面,你的意图UI扩展可以自行配置不同风格,具体取决于该请求是否来自Siri或地图。

创建意图扩展 Intents Extension

Siri和地图通过你的意图的扩展与应用程序交互。意图的入口是 INExtension对象,其唯一的工作就是直接的从Siri到能够响应用户请求的对象。实现意图扩展时,有三种类型的对象,你经常使用:

  • 意图对象 intent object :由用户意图定义的意图对象并且包含siri从用户那收集来的数据

  • 处理对象 handler object:处理对象是一个自定义用来解决,确认,处理一个意图的对象。

  • 响应对象 response object :响应对象是一个包含响应给意图数据的对象

当你的扩展来处理意图, Siri向INExtension对象请求处理对象。处理对象可以是你想要的任意类型,但是必须实现处理给定意图的方法,每个意图有一个必须采用的附加协议,协议的方法分为三组:解决方法,确认方法,和处理方法,你实现你需要的方法并提供关于你如何处理意图的信息给Siri

图2 - 1 说明了在你的扩展中 Siri和处理对象之间高级别流。在此示例中,当用户想要预订一程车辆预订服务,Siri将创建一个意图对象与车辆参数并将其发送给处理程序。处理程序解析意图对象中的数据值,来满足车辆需求。当所有车辆参数被解决,Siri要求处理程序确认计划如何处理车辆请求,执行任何最终验证。在确认阶段,处理程序提供了一个关于车辆的响应对象详细信息,Siri可能显示给用户。如果用户接受车辆请求,Siri要求车辆请求处理意图的处理对象。处理程序响应并返回一个带有预订车辆细节的响应。
在确认阶段,该处理程序响应对象提供乘车,Siri 可能会向用户显示的详细信息。如果用户接受骑,Siri 询问骑请求处理程序来处理的意图。该处理程序响应通过预订乘坐并返回响应一个预订乘车的细节。

图2 - 1 处理一个车辆请求意图

技术分享

有关如何创建扩展的一些信息, 查阅 App Extension Programming Guide.

配置你的 Xcode工程 Configuring Your Xcode Project

支持SiriKit,为你的iOS应用程序添加一个意图扩展。

添加一个意图扩展到你的APP

  1. 在Xcode中打开已经存在的iOS app
  2. Select File > New > Target.
  3. 从合适的平台的Application Extension分组中选择  Intents extension
  4. 点击Next.
  5. 指定您的扩展的名称和配置语言和其他选项。如果您计划自定义部分 Siri UI,启用并包括Include UI Extension选项。
  6. 点击 Finish.

Xcode 提供的意图扩展模板包括 INExtension 子类供您自定义。你使用该类创建需处理意图的处理程序对象。Siri 使用您的扩展的Info.plist 文件来发现它支持的意图。Xcode 提供了Info.plist 文件包含了大多数配置,但您必须修改它来指定您的扩展处理哪些意图的部分。

指定您的应用程序支持的意图︰

  1. 在Xcode, 选择意图扩展的Info.plist文件
  2. 展开 NSExtension 和 NSExtensionAttributes keys查看IntentsSupported 和 IntentsRestrictedWhileLocked keys
  3. IntentsSupported key, 添加每个你计划支持的意图字符串。每一项的值设置为意图的类名。这个 key是必须的,你可以在给定领域中支持你想要的全
  4. 部或部分的意图,值必须包含支持您的扩展的所有意图的类
  5. IntentsRestrictedWhileLocked key, 为任何你仅支持在用户的设备处于解锁状态时的意图添加字符串项。每一项的值设置为意图的类名。这个 key 是
  6. 可选的.其值包含您需要解锁的设备的意图类子集。如果处理意图涉及访问受保护的磁盘文件或操纵敏感的用户数据。你可能需要包括在如下列表中的意图

实现您的扩展的行为涉及以下任务 ︰

  • 为你支持的每个意图定义处理类,你可以为每个意图定义处理类,或者定义为多个意图定义一个处理类,使用的协议让任何对象转化为意图处理对象变得更加容易
  • 添加自定义的源文件,为了任何支持的意图需要执行的任务。您的扩展必须能够执行任何与意图关联的任务。例如,车辆预订服务的处理程序必须能够预订车辆和获取有关使用该预定服务的信息。无论什么源文件添加到扩展项目,你需要保证这一点;请参阅Structuring Your App’s Services。
  • 更新 Xcode 提供的默认 INExtension 类。修改 handlerForIntent 方法︰ Xcode提供的 INExtension 子类创建并返回您的自定义处理程序对象的方法。有关如何实现此方法的信息,请参阅 INIntentHandlerProviding Protocol Reference 。
  • 定义您的应用程序使用的任何自定义的词汇。以特定方式使用应用程序的单词或短语可以定义一个自定义的词汇文件来帮助 Siri 明白该自定义的用法。有关如何使用您的应用程序的自定义词汇提供 给Siri 信息,请查阅 Specifying Custom Vocabulary 章节

可用的意图和关联的类与协议的列表,请参阅 Intents Domains。

在iOS应用程序中请求Siri授权

在你的意图扩展可以使用之前,和任何特定于用户的词汇注册之前,你的 iOS 应用程序必须请求使用 Siri 的授权。若要请求授权,请执行以下操作 ︰

  • 在您的应用程序的 Info.plist 文件中包含 NSSiriUsageDescription 键。此键的值是一个字符串,描述您的应用程序处理意图向 Siri 发送什么数据。例如,一个健身应用程序可能会将值设置为字符串"健身信息将被发送到 Siri。"
  • 程序中调用 requestSiriAuthorization  在应用程序执行期间合适的时机调用  INPreferences 的类方法requestSiriAuthorization

你的 iOS 应用程序第一次调用 requestSiriAuthorization  时候︰ 方法,系统会显示一个Alert提示框,提示用户授权您的应用程序。Alert提示框包括在您的应用程序的 Info.plist 文件的 NSSiriUsageDescription 所提供的使用说明字符串。用户可以批准或拒绝您的应用程序的授权请求,并可以在后来iOS系统设置中更改您的应用程序的授权状态。系统会记住您的应用程序的授权状态以便后续对 requestSiriAuthorization 的调用时不会再次提示用户。

构建应用程序的服务

您的意图扩展代理您的应用程序行为,应该能够执行与您的应用程序相同的服务。因为你的 iOS 应用程序和意图扩展会执行许多相同的任务,考虑以下方面 ︰

  • 使用一个私人的共享的框架(.framework)来存储您的核心服务的代码。链接(.framework)到到您的 iOS 应用程序与您的意图扩展。共享的框架可以使这两个可执行文件最小化,并确保两者都使用相同的代码与您的服务进行交互。
  • 使用一个共享的容器来存储共同资源。如果您的服务使用图像或数据文件并放在App bundle中,将这些资源放入共享的容器内。启用共享的容器支持每一个target
 

测试你的意图扩展

若要测试您的意图扩展,必须在设备上运行它。Xcode提供直接运行工程到设备上的供调试
在设备上运行和调试你的意图扩展
  1. 激活你的意图扩展中的一个scheme,当您向项目中添加一个意图扩展时,Xcode 会自动创建用于运行该扩展的scheme。
  2. 配置scheme在连接设备上运行。你不能在模拟器上调试你的意图扩展
  3. 选择Product > Run 使您的扩展到设备上。
  4. 在Xcode提示时,选择Siri作为应用程序运行。Xcode构建应用程序和扩展,安装在设备上,并启动Siri。

首次安装扩展时,Siri可能不会立刻认出你的应用扩展。你可能需要等待几分钟才能发出任何相关命令。同样的,当更新你的信息。plist文件,您可能需要等待几分钟,Siri才会认识到变化。

在应用程序中使用意图框架 Intents.Framework

你的iOS应用程序使用意图框架来执行特定的任务:

  • 使用INVocabulary类注册用户特定的词汇表术语。为了app特定的用户注册用户特定的词汇术语,否则可能会被误解Siri;请不要注册常见或很容易理解的术语。有关注册词汇的信息,请参阅 Specifying Custom Vocabulary 章节
  • 使用INPreferences类获取Siri语言与本地化内容。使用这些信息格式化你的应用和扩展的任何内容。有关更多信息,请参见 INPreferences Class Reference。
  • 创建 INInteraction 对象当你想要donate系统的相互作用,创建 INInteraction 对象。donate的相互作用,可以提供用户正在做什么的上下文  。系统和其他应用程序可以使用这些信息来改善搜索结果,提供更好的用户体验。更多的信息,请参阅 INInteraction Class Reference。

Siri 国际化

用户可以为了Siri配置不同的语言。在 iOS应用程序中,系统使用特定的设备的语言设置检索本地化的内容。在您的意图扩展中,系统检索使用 Siri 语言的本地化的内容。如果您的应用程序与您的扩展共享本地化的内容,您必须使用 Siri 语言共享内容,您的应用程序可以通过INPreferences类的 siriLanguageCode 方法检索。
Siri语言的更多信息,请参阅INPreferences Class Reference

解析和处理意图 Resolving and Handling Intents

在您的意图扩展中,处理程序对象的重要工作就是、解析, 确认,并处理Siri发送的意图对象。每个意图对象有一个相关联的协议,为处理意图专门设计的。例如,INRequestRideIntent 对象的处理程序采用 INRequestRideIntentHandling 协议。

每个协议的方法分为三组:

  • 为解析意图参数的零个或更多的方法
  • Siri 提供的建议响应的确认方法

执行任务的处理方法

当实现一个处理程序,您总是必须实现处理意图的方法。所有其他方法都是可选,但建议,解析和确认方法是在你试图处理它之前的机会来验证一个意图的内容。您还可以使用这些方法来标识或创建您需要处理的意图的内部数据对象。

意图和相应的意图处理协议的列表,参阅 Intents Domains。

解析意图的参数

在意图的决议阶段,Siri 会询问您的处理程序来解析关键参数,确认您要使用的值。因为来自用户的数据是口语,有可能会丢失或不明确的信息。决议阶段是你来验证提供的数据的机会,并让 Siri 知道是否你需要澄清或更多的信息。建议您执行所有决议方法为给定的处理程序的协议。虽然你不可能使用的所有参数,每个方法告诉 Siri 是否您在您自己的数据结构中确定一个适当的值。

您将组织决议结果反馈到SiriKit后使用决议后结果对象,结果对象是INIntentResolutionResult类的实例。您可能需要去解析不同的子类的每个参数的类型。例如,当解析格式化一个INPerson对象, 你会返回 INPersonResolutionResult 类的一个实例。实例化你的子类使用对应于您决议的结果的对应方法。表 3-1 列出了可能的结果和解释什么时候使用哪一个。

表格 3-1 当解析意图参数可能出现的结果

决议Resolution

例子

你成功的匹配到了值

指定该决议,当你成功地验证了参数和相应的值可以用来处理的意图时。这个结果是最可取的,因为它不需要进一步的用户交互,

你应该采取措施来解析参数成功。

例如,您可以利用用户模式或最喜欢的识别可能值参数。

一个值并不是必需的

指定该决议时不需要参数的值来处理意图。通常,返回这个结果只有当一个参数使用的一些时间和当前没有相关。

例如,当意图包含为一个开放的健身目标时您可能会返回这个结果,通常没有目标。

值需要消歧

指定该决议,当确定两个或两个以上可能的结果时,不能选择一个明确的结果。这个结果通常会导致额外的用户交互来消除歧义参数。

例如,如果一个消息接收者被称为“Brandon”但是用户有两个联系人叫这个名字,你可以用这个结果寻求帮助,选择正确的一个。

值需要用户确认

指定这个结果时, 当你想让Siri提示用户确认的指定值。Siri总是要求确认涉及金融交易的意图,但是你可以在这种这种情况下使用,您希望用户确认你提供的值。

例如,您可以请求确认收件人的音频电话。

值需要更多的细节

对于一个给定的信息不完整的参数指定这个结果时。一些参数是一对象可能有多个信息。

例如,使用这个结果如果一个INPerson对象不包含足够的细节来识别一个特定的联系人和你不能从可用的信息作出合理的猜测。使用这个决议,要求用户提供错过的的信息。

值是必需的

所需参数的值丢失时指定这个结果。Siri询问您的扩展来解析每一个参数,不管用户是否指定一个参数的值。当您需要一个值去处理的时候使用这个决议继续。

例如,如果用户请求付款没有指定数量,您可能会返回这个结果,。

值是不支持的

当你的应用程序不支持一个特定的值或值与其他参数冲突指定这个结果。您必须指定一个参数为什么无效的原因。你也可以选择指定有效的替代值。

例如,您可能会返回这个结果当用户想要发送一个支付瑞士法郎,但你的应用需要欧元或美元。当提供一个列表的替代值时,只提供最可能的替代值,而不是每一个可能的值。提供太多的选择可能会让用户很难选择正确的一个。

当解析参数时,尽可能快的试图达到一个成功决议。要求更多的信息会导致额外的用户交互和额外的处理程序调用,它会增加延迟和可能阻挠用户。相反,基于用户的模式和习惯尽量选择合理的值,并要求消歧或只在需要的时候确认。

清单 3-1 显示一个例子,从车辆预约app到验证还车地点。如果一个还车地点是存在的,该方法将返回一个成功的结果;否则,该方法返回一个结果表明返回值是必须的

清单3-1 解析意图所需的参数

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//Objective-c
- (void)resolveDropOffLocationForRequestRide:(INRequestRideIntent *)requestRideIntent
            withCompletion:(void (^)(INPlacemarkResolutionResult *resolutionResult))completion {
    CLPlacemark* location = requestRideIntent.dropOffLocation;
    INPlacemarkResolutionResult* result = nil;
 
    if (location) {
       // Use the specified drop-off location.
       result = [INPlacemarkResolutionResult successWithResolvedPlacemark:location];
    }
    else {
       // Ask for the drop-off location.
       result = [INPlacemarkResolutionResult needsValue];
    }
 
    // Execute the completion block with the result.
    completion(result);
}

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//Swift
func resolveDropOffLocation(forRequestRide intent: INRequestRideIntent,
                            with completion: (INPlacemarkResolutionResult) -> Void) {
    let location = intent.dropOffLocation
    var result : INPlacemarkResolutionResult
    
    if location != nil {
        // Use the specified drop-off location.
        result = INPlacemarkResolutionResult.success(with: location!)
    }
    else {
        // Ask for the drop-off location.
        result = INPlacemarkResolutionResult.needsValue()
    }
    
    // Execute the completion block with the result.
    completion(result);
}

 

确认请求

所有意图的参数已获得圆满的解析后,处理程序被要求确认的意图的详细信息,提出一个响应。 所有参数都已成功地得到解析或不需要继续解析满意的决议。在确认期间,您可以执行额外的验证所有意图参数,确保您可以使用该信息来执行所请求的服务。

在您的处理程序中实现确认方法不是必需的但是强烈建议。Siri总是提示用户确认重要的请求,特别是那些不能撤销或涉及金融交易。Siri在其他情况下可能或不会提示用户。无论哪种方式,执行确认方法是好的方式,以确保您能够提供响应。

清单 3-2 显示了开始健身的简单确认方法。确认方法的主要工作是执行提供的block与响应对象。本示例创建一个响应对象,表明健身可以成功启动。如果你想要执行任何额外的验证,可以使用此方法去做。

清单3-2 确认健身的开始

 

 
1
2
3
4
5
6
7
8
9
10
11
12
//Objective-c
- (void)confirmStartWorkout:(INStartWorkoutIntent *)startWorkoutIntent
                 completion:(void (^)(INStartWorkoutIntentResponse * _Nonnull))completion {
   NSUserActivity  *activity = [[NSUserActivity alloc]
            initWithActivityType:@"startWorkoutActivityType"];
   INStartWorkoutIntentResponse* response = [[INStartWorkoutIntentResponse alloc]
            initWithCode:INStartWorkoutIntentResponseCodeSuccess userActivity:activity];
 
   // Perform any final validation.
 
   completion(response);
}

 

 
1
2
3
4
5
6
7
8
9
10
11
//Swift
 
    func confirmStartWorkout(startWorkout intent: INStartWorkoutIntent,
                             completion: (INStartWorkoutIntentResponse) -> Void) {
        let activity = NSUserActivity(activityType: "startWorkoutActivityType")
        let response = INStartWorkoutIntentResponse(code: .success, userActivity: activity)
        
        // Perform any final validation.
        
        completion(response)
    }

了解每个意图创建的响应对象的更多信息,参阅Intents Domains。

处理请求

处理的意图的最后阶段是执行意图与意图关联的操作。您的处理程序对象的处理方法有两个责任 ︰

  • 执行与意图相关联的任务
  • 返回一个关于你的应用的响应对象信息。

处理一个任务时,连接到你的服务并执行相关任务。执行任务的实现细节完全是你的责任。例如,旅行预订服务连接到公司网络服务器请求和返回结果。

除了执行任务,创建一个响应对象包含你的详细信息。信息中放入每个不同意图的响应对象 ,和可能比其他人需要更多的信息的一些响应对象。你也应该为NSUserActivity对象提供任何额外的细节,您的应用程序可能需要继续任务。用户可以选择立即启动您的应用程序以获得更多细节。如果发生这种情况,用户活动对象activity object应包含任何信息,您需要配置您的应用程序的界面接口与任务的细节。

清单3显示了一个处理方法,刚开始健身的状态报告。在这个例子中,该处理程序调用自定义方法,通知指定的应用程序开始健身前返回一个响应给Siri。

清单3-处理健身的开始

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
//Objective-C
- (void)handleStartWorkout:(INStartWorkoutIntent *)startWorkoutIntent
                completion:(void (^) (INStartWorkoutIntentResponse * _Nonnull))completion {
   NSUserActivity  *activity = [[NSUserActivity alloc]
               initWithActivityType:@"startWorkoutActivityType"];
   INStartWorkoutIntentResponse* response = [[INStartWorkoutIntentResponse alloc]
               initWithCode:INStartWorkoutIntentResponseCodeSuccess userActivity:activity];
 
   // Do the work…
   [self startWorkoutWithName:startWorkoutIntent.workoutName];
 
   completion(response);
}

 

 
1
2
3
4
5
6
7
8
9
10
11
//Swift
func handleStartWorkout(startWorkout intent: INStartWorkoutIntent,
                        completion: (INStartWorkoutIntentResponse) -> Void) {
    let activity = NSUserActivity(activityType: "startWorkoutActivityType")
    let response = INStartWorkoutIntentResponse(code: .success, userActivity: activity)
    
    // Do the work…
    self.startWorkout(startWorkoutIntent.workoutName!)
    
    completion(response)
}

在您的意图扩展所做的更改也应反映在你的 iOS 应用程序的界面。作为处理任务的一部分,您的扩展应将任何所需的数据提供给你的iOS 应用程序。即使您可以提供一个 INInteraction 对象与意图和您的响应的详细信息,在所有情况下用户活动对象(activity objects)不会传递到您的应用程序。例如,用户可能会启动应用程序,而无需使用切换。为了确保您的应用程序是最新的,您的扩展可以放置任何更新文件在您的应用程序可访问的的共享容器。您的应用程序然后可以使用后台应用程序刷新以获取任何更改和更新。

了解每个意图创建的响应对象的更多信息,参阅Intents Domains。

指定自定义词汇表 Specifying Custom Vocabulary

Apps有自定义的词汇可以告知 Siri 对该词汇的正确使用。自定义词汇是指 Siri 可能不理解自然语言的任何术语。例如,一个车辆预订app引用的特定车辆类型"Vroom",app为 Siri 定义这个词,并提供有关用户如何使用它的例子。定义您的应用程序的词汇给 Siri ,了解有关您的应用程序的用户命令,有助于提高整体的用户体验。

有两种方法来定义应用程序的自定义词汇:

  • 若要注册特定于单个用户的术语,请使用 INVocabulary 对象。
  • 若要向您的应用所有用户程序注册共同的术语,请将 AppIntentVocabulary.plist 文件添加到您的 iOS 应用程序。

重要提醒:Siri 对待自定义词汇作为提示,Siri会纳入尽可能多的你自定义的词汇。然而,自定义词汇的空间是有限的,你注册过多的词汇的用法可能会混淆,否则,保持注册术语总数尽可能小。

注册特定用户词汇

使用共享的 INVocabulary 对象来注册,特定于单个用户的词汇。特定于用户的术语必须属于以下类别之一 ︰

  • 联系人姓名 (如果他们不受contacts框架管理)
  • 照片标签
  • 图片专辑名称
  • 运动名称

当选择词汇来注册,选择术语可能会被不熟悉您的应用程序的人误解。例如,消息的应用程序(messaging app)可能注册屏幕名称从用户的收藏夹列表。请不要注册很容易理解的术语,如"我的相册"或"我的健身"的条目。相反,专注于其字面意思不同于您的应用程序使用中的这些术语的词汇。

注册的每个类别的术语集,使用 setVocabularyStrings:ofType: 方法。注册一套新的术语替换为该类别旧的的条目,因此你需要您每次调用该方法。不要包括每个可用的可能的术语。相反,专注于与用户的收藏夹、常用的术语或最近使用的术语相关的术语。最重要的是术语总是应该在你创建的 NSOrderedSet 对象中。

清单 4-1 显示了注册自定义的健身术语集的示例。应用程序排序的基础使用了他们最后一次的健身的名称,把大部分用于健身的术语放到ordered set中。通常情况下,您注册用户特定术语不是从您的应用程序中,而是从您的意图扩展。

清单4-注册特定于用户的词汇

 

 
1
2
3
4
5
6
//Objective-C
NSOrderedSet* workoutNames = [self sortedWorkoutNames];
 
INVocabulary* vocabulary = [INVocabulary sharedVocabulary];
[vocabulary setVocabularyStrings:workoutNames
              ofType:INVocabularyStringTypeWorkoutActivityName];

 

 
1
2
3
4
5
//Swift
let workoutNames = self.sortedWorkoutNames()
 
let vocabulary = INVocabulary.shared()
vocabulary.setVocabularyStrings(workoutNames, of: .workoutActivityName)

 

注册一套术语并不是一个保证他们之后会受到 Siri识别。Siri将您提供任何术语视,如果它可以提示和使用它们。如果它可以。为此,
重要的是关注那些术语对于你的应用程序是唯一的或者特定用户的条件使用,不要包括通用术语或用户不会通过Siri说出来的术语。

关于注册用户特定词汇表术语的额外信息,请参阅INVocabulary Class Reference

创建全局的词汇文件

使用一个全局词汇表文件登记词汇对于应用程序的所有用户是很常见的。全局术语必须属于下列情形之一:

  • 路线的选择  Ride options
  • 健身的名称 Workout names

一个全局性的词汇文件是称为 AppIntentVocabulary.plist 的属性列表文件。将此文件放在.lproj 目录中对应于您的应用程序基础的开发语言。在您的应用程序的特定的语言的项目 (.lproj) 目录中包含本地化的版本。在 Xcode中,你可以从文件检查器创建本地化的版本自动的。

创建全局词汇表文件

  1. 选择 New > File.
  2. 在 iOS > Resource, 选择 Property List文件类型.
  3. 点击 Next.
  4. 设置文件名称为 AppIntentVocabulary.plist
  5. 点击Create
  6. 在工程中选择AppIntentVocabulary.plist文件
  7. 在Root element.中增加两个key 。设置第一个 key 为 ParameterVocabularies 设置第二个key 为 IntentPhrases

全局词汇表文件包在根级别含两个键:

  • ParameterVocabularies 键定义您的应用程序的自定义术语和适用的意图参数。
  • IntentPhrases 键包含包含您自定义的术语的示例短语

对于每个自定义的术语,指定术语,该术语所适用的意图属性。一个单一的术语可能与多个意图关联。例如,自定义健身名称可以同样适用于所有其他的健身有关的意图类。除了术语和意图的信息,同时为SiriKit放置意图对象,指定对象标识符字符串。在解析期间,你将解析该标识符字符串为健身。

重要提示:在开发过程中,Xcode 将全局词汇转发到Siri,但会限制词汇对你开发设备的可用性。迁移你的词汇量数据不是即时的,所以你可能测试任何自定义的词汇前需要等待一两分钟。

关于全局词汇表文件的详细信息的结构和键,参阅 App Vocabulary File Format。

提供自定义的界面 Providing a Custom Interface

Siri 和地图应用程序显示您的意图扩展所提供的信息,但您可以自定义所显示的内容,使用意图UI扩展部分(Intents UI extension)。意图用户界面扩展的用途是自定义的 Siri 或地图的界面,以便让用户知道是您的应用程序提供响应。例如,您可能会添加到你的品牌相关的视觉元素或提供额外的信息与相关的请求,但不是标准界面的一部分。

意图 UI 扩展(Intents UI extension)包含一个视图控制器与您的应用程序响应相关的信息。您可以自定义显示信息的任何或所有您的应用程序支持的意图。当显示响应的一个受支持的意图时,Siri 和地图融入从意图户UI扩展中的视图控制器到他们显示的界面中。

使用传递到你的视图控制器的响应数据配置任何视图的内容并决定要显示什么内容。你可能会显示任何有关您的品牌或对用户有用的信息。但是。。。你可能无法显示广告。
您可以提供意图UI扩展来支持相关的车辆预定、 消息、 付款及健身的意图。哪些情况可能会使用到意图UI界面扩展的,一些例子如下 ︰

  • 打车显示附加车辆详细信息品牌
  • 消息使用品牌颜色样式显示消息内容
  • 付款显示品牌其他付款相关信息
  • 健身显示自定义健身信息品牌

意图 UI 扩展可能支持多个的意图,但所有的意图共享相同的视图控制器。您的视图控制器基于当前的意图和显示环境影响不同接收到足够的信息来配置本身。大多数的意图通过Siri显示 ,但车辆预定意图通常显示在地图应用程序中。

配置你的Xcode工程

自定义 Siri 界面请将意图 UI 扩展 添加的 iOS 应用程序创建意图扩展可以添加扩展晚些时候可以添加项目
添加意图扩展到你的应用程序
  • 在 Xcode 中打开您现有的 iOS 应用程序项目。
  • 选择File > New > Target。
  • 从 iOS 应用程序扩展组( iOS Application Extension)中,选择意图UI界面扩展(Intents UI extension)。
  • 单击Next。
  • 指定您的扩展的名称和配置语言和其他选项。
  • 单击Finished。

Xcode 提供的意图UI扩展模板包含演示图板与单一视图控制器。Siri 和地图总是加载和storyboard文件中显示的initial view controller,因此配置该视图控制器与你想要显示的内容。如果你想要显示的视图的每个意图不同视图集,创建子视图控制器并将它们嵌入到您在运行时的初始视图控制器。

您的意图UI扩展的 Info.plist 文件告诉 Siri支持哪些意图扩展。表 5-1 列出必须包含在您的扩展的 Info.plist 文件中的NSExtension 键。您在 NSExtensionAttributes关联的字典中键指定支持的意图。

表5-1 意图UI扩展的plist文件Keys信息

键 Key

描述 Description

NSExtensionAttributes

与此键关联的词典必须包含其值是一个字符串数组,IntentsSupported 键。每个字符串的值是扩展支持意图类的名称。

NSExtensionMainStoryboard

此键的值是包含您的扩展视图控制器的。storyboard文件的名称。如果您希望以编程方式创建您的视图控制器的系统,可以用 NSExtensionPrincipalClass 键代替这一个。

NSExtensionPointIdentifier

这个键的值必须为字符串 com.apple.intents-ui-service.

实现视图控制器

显示响应之前,您的意图UI界面扩展storyboard的初始视图控制器initial view controller负责显示您的内容。Siri 或地图应用程序加载该视图控制器和调用其 configureWithInteraction:context:completion ︰方法。使用该方法从交互对象来配置您的视图控制器的内容和编写它出现在屏幕上。使用上下文参数并根据 Siri 或映射接口需要调整您的内容的演示文稿。

在屏幕上,你的视图控制器仍是foreground interface的一部分,直到用户dismisses了Siri或者地图界面。你可以根据需要更新您的视图控制器的接口使用计时器或其他编程手段,和视图控制器参与正常视图控制器进程加载时,显示和隐藏。虽然在屏幕上,你的视图控制器不接收触摸事件和其他响应链responder-chain事件,你不能添加手势识别器或试图拦截事件在其他途径。因此,需要用户交互不应该包括控制或视图

图 5-1 显示您的意图UI扩展和其视图控制器的生命周期。系统创建您的视图控制器并调用其 configureWithInteraction:context:completion ︰方法,交互对象传递给它后您需要配置您的界面。配置完成后,您的视图控制器与其余的 Siri 或地图的内容显示在屏幕上。虽然在屏幕上,您的视图控制器可以运行动画并更新本身使用计时器和其他的手段,但它不能接收触摸事件或响应链事件。

图5-1 意图UI扩展的生命周期

技术分享

当用户关闭 Siri 或地图的界面时,系统将释放其引用到你的视图控制器和您的意图UI扩展。视图控制器应仅用于显示信息。当您的视图控制器移动屏幕外,不要试图将数据保存或与您的应用程序直接沟通。

这里有一些建议来实现对你的意图UI视图控制器扩展:

  • 将你的品牌纳入到你的界面。使用您的应用程序的颜色、 图像和其他设计元素,这是一个伟大的方式来增加熟悉和传达您的应用程序的存在。
  • 子视图控制器child view controllers用于不同类型的内容之间进行切换。您的意图UI扩展了只有一个主视图控制器。如果您想显示不同的内容,不同的意图,使用子视图控制器管理视图相关的意图。在你的configureWithInteraction:context:completion ︰ 方法、 安装基于提供的意图对象的子视图控制器。
  • 在视图控制器可见时配置任何动画的内容运行。视图控制器 viewDidAppear ︰ 调用方法来启动动画。在视图控制器viewWillDisappear ︰ 方法停止动画。
  • 尽可能快地配置您的视图控制器的视图,这样 Siri可以显示它。您的视图控制器可能不在屏幕上很长时间,所以配置大量使用本地资源和提供的INInteraction 对象。如果您需要从服务器获取更多的信息,异步请求和然后更新您的界面。
  • 在界面中不要包含广告。可以包括品牌和与用户相关的信息,但禁止广告。

配置视图控制器的更多信息,请参阅INUIHostedViewControlling Protocol Reference

替换默认界面

车辆预订和消息意图,如果它与您提供的内容相冲突,你可以隐藏由系统提供默认内容。对于消息的意向,Siri 会显示消息内容和收件人。对于车辆预订意图,Siri 和地图应用程序显示一张地图,显示用户的位置。如果你你自己的界面提供相同的信息,使用 INUIHostedViewSiriProviding 协议的属性来禁止显示的系统界面。

sirikit