iOS 11 中的 SiriKit 更新

SiriKit 是在 iOS 10 中引入的,有许多服务域(包括锻炼、乘车预订和拨打电话)。 请参阅 SiriKit 部分 了解 SiriKit 概念,以及如何在应用中实现 SiriKit。

Siri task list demo

iOS 11 中的 SiriKit 添加了这些新的和更新的意向域:

  • 列表和备注 –新增! 为应用提供用于处理任务和笔记的 API。
  • 视觉代码 – 新增! Siri 可以显示 QR 码来共享联系信息或参与付款交易。
  • 付款–添加了付款交互的搜索和转移意向。
  • 乘车预订–添加了取消乘车和反馈意向。

其他新功能包括:

  • 备用应用名称–提供别名,帮助客户通过提供备用名称/发音来告知 Siri 来定位你的应用。
  • 开始锻炼–提供在后台开始锻炼的能力。

下面介绍了其中一些功能。 有关其他文档的更多详细信息,请参阅 Apple 的 SiriKit 文档

列表和备注

新的列表和备注域为应用提供了一个 API,用于通过 Siri 语音请求处理任务和笔记。

任务

  • 具有标题和完成状态。
  • (可选)包括截止时间和位置。

说明

  • 具有标题和内容字段。

任务和笔记都可以组织成组。 本部分的其余部分介绍如何通过使用 TasksNotes SiriKit 示例,使用 siriKit 实现此新域。

如何处理 SiriKit 请求

按照以下步骤处理 SiriKit 请求:

  1. 解决–验证参数,并请求用户(如果需要)的进一步信息。
  2. 确认–最终验证和核实是否可以处理请求。
  3. 句柄–执行操作(更新数据或执行网络操作)。

前两个步骤是可选的(尽管鼓励这样做),最后一步是必需的。 SiriKit 部分中提供了更详细的说明。

解析和确认方法

这些可选方法允许代码执行验证、选择默认值或从用户请求其他信息。

例如,对于 IINCreateTaskListIntent 接口,所需的方法是 HandleCreateTaskList。 有四种可选方法可以更好地控制 Siri 交互:

  • ResolveTitle - 验证游戏、设置默认标题(如果适用),或指示不需要数据。
  • ResolveTaskTitles–验证用户所说的任务列表。
  • ResolveGroupName–验证组名称、选择默认组或指示不需要数据。
  • ConfirmCreateTaskList–验证代码是否可以执行请求的操作,但不执行它(只有 Handle* 方法应修改数据)。

处理意向

列表和备注域中有 6 个意向,3 个意向用于任务,3 个意向用于备注。 必须实现以处理这些意向的方法包括:

  • 对于任务:
    • HandleAddTasks
    • HandleCreateTaskList
    • HandleSetTaskAttribute
  • 有关说明:
    • HandleCreateNote
    • HandleAppendToNote
    • HandleSearchForNotebookItems

每个方法都有一个传递给它的特定意向类型,其中包含从用户请求分析的所有信息(并且可能在 Resolve*Confirm* 方法中更新)。 你的应用必须分析提供的数据,然后执行一些操作来存储或处理数据,并返回 Siri 对用户说话和显示的结果。

响应代码

所需的 Handle* 和可选的 Confirm* 方法通过设置传递给其完成处理程序的对象上的值来指示响应代码。 响应来自 INCreateTaskListIntentResponseCode 枚举:

  • Ready–在确认阶段(即方法 Confirm* 中,而不是方法中 Handle*)返回。
  • InProgress–用于长时间运行的任务(如网络/服务器操作)。
  • Success–使用成功操作的详细信息(仅从 Handle* 方法)进行响应。
  • Failure–表示发生了错误,并且无法完成操作。
  • RequiringAppLaunch–不能由意向处理,但可以在应用中执行该操作。
  • Unspecified–请勿使用:将向用户显示错误消息。

在 Apple SiriKit 列表和说明文档中详细了解这些方法和响应。

实现列表和备注

TasksNotes SiriKit 示例 是使用以下步骤将 SiriKit 支持添加到空白 iOS 应用创建的。

首先,若要添加 SiriKit 支持,请针对 iOS 应用执行以下步骤:

  1. Entitlements.plist 中的勾选 SiriKit
  2. 隐私–Siri 使用情况说明密钥添加到 Info.plist,并为客户附上一条消息。
  3. 在应用中调用 INPreferences.RequestSiriAuthorization 方法,提示用户允许 Siri 交互。
  4. 在开发人员门户中将 SiriKit 添加到应用 ID,并重新创建预配配置文件以包含新权利。

然后将新的扩展项目添加到应用以处理 Siri 请求:

  1. 右键单击解决方案,然后选择“添加 > 添加新项目...”。
  2. 选择 iOS > 扩展 > 意向扩展 模板。
  3. 将添加两个新项目:Intent 和 IntentUI。 自定义 UI 是可选的,因此示例仅包含意向项目中的代码。

扩展项目是将处理所有 SiriKit 请求的位置。 作为单独的扩展,它不会自动与主应用通信,这通常是通过使用应用组实现共享文件存储来解决的。

配置 IntentHandler

IntentHandler 类是 Siri 请求的入口点,每个意向都会传递给 GetHandler 方法,该方法会返回一个可以处理请求的对象。

下面的代码显示了一个简单的实现:

[Register("IntentHandler")]
public partial class IntentHandler : INExtension, IINNotebookDomainHandling
{
  protected IntentHandler(IntPtr handle) : base(handle)
  {}
  public override NSObject GetHandler(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 this;
  }
  // add intent handlers here!
}

该类必须继承自 INExtension,因为示例将处理列表和笔记意向,因此它还实现 IINNotebookDomainHandling

注意

  • .NET 中有一个约定,接口的前缀为大写 I,Xamarin 在从 iOS SDK 绑定协议时遵循该约定。
  • Xamarin 还保留 iOS 中的类型名称,Apple 使用类型名称中的前两个字符来反映类型所属的框架。
  • 对于 Intents 框架,类型以 IN*(例如 INExtension)为前缀,但这些类型是接口。
  • 它还遵循协议(在 C# 中成为接口)最终会得到两个 I,例如 IINAddTasksIntentHandling

处理意向

每个意向(添加任务、设置任务属性等)都是在类似于下面所示的单个方法中实现的。 该方法应执行三个主要函数:

  1. 处理意向–Siri 分析的数据在特定于意向类型的 intent 对象中提供。 你的应用可能已使用可选 Resolve* 方法验证了该数据。
  2. 验证和更新数据存储–将数据保存到文件系统(使用应用组,以便主 iOS 应用也可以访问它),或通过网络请求。
  3. 提供响应 – 使用 completion 处理程序将响应发送回 Siri 以向用户读取/显示:
public void HandleCreateTaskList(INCreateTaskListIntent intent, Action<INCreateTaskListIntentResponse> completion)
{
  var list = TaskList.FromIntent(intent);
  // TODO: have to create the list and tasks... in your app data store
  var response = new INCreateTaskListIntentResponse(INCreateTaskListIntentResponseCode.Success, null)
  {
    CreatedTaskList = list
  };
  completion(response);
}

请注意,null 会作为第二个参数传递给响应,这是用户活动参数,如果未提供,则将使用默认值。 只要 iOS 应用通过 info.plist 中的 NSUserActivityTypes 密钥支持它,就可以设置自定义活动类型。 然后,可以在打开应用时处理这种情况,并执行特定操作(例如打开相关视图控制器并从 Siri 操作加载数据)。

该示例还对 Success 结果进行硬编码,但在实际情况下,应添加正确的错误报告。

测试短语

以下测试短语应在示例应用中工作:

  • “在 TasksNotes 中使用苹果、香蕉和梨制作杂货清单”
  • “在 TasksNotes 中添加任务 WWDC”
  • “将任务 WWDC 添加到 TasksNotes 中的训练列表”
  • “在 TasksNotes 中标记为完成 WWDC”
  • “在 TasksNotes 中提醒我回家时买一部 iphone”
  • “在 TasksNotes 中将购买 iPhone 标记为已完成”
  • “在 TasksNotes 中提醒我上午 8 点离开家”

Create a new list exampleSet task as complete example

注意

iOS 11 模拟器支持使用 Siri 进行测试(与早期版本不同)。

如果在真实设备上进行测试,请不要忘记配置应用 ID 和预配配置文件以支持 SiriKit。

可选名称

这个新的 iOS 11 功能意味着你可以为应用配置备用名称,以帮助用户使用 Siri 正确触发它。 将以下键添加到 iOS 应用项目的 Info.plist 文件:

Info.plist showing alternative app name keys and values

设置备用应用名称后,以下短语也适用于示例应用(实际上命名为 TasksNotes):

  • “在 MonkeyNotes 中使用苹果、香蕉和梨制作杂货清单”
  • “在 MonkeyTodo 中添加任务 WWDC”

疑难解答

运行示例或将 SiriKit 添加到自己的应用程序时可能会遇到的一些错误:

NSInternalInconsistencyException

引发 Objective-C 异常。 名称:NSInternalInconsistencyException 原因:从应用程序使用类 <INPreferences: 0x60400082ff00> 需要 com.apple.developer.siri.NET 权限。 是否在 Xcode 项目中启用 Siri 功能?

  • entitlements.plist 中勾选 SiriKit。

  • 在“项目选项 > 生成 > iOS 捆绑签名”中配置 Entitlements.plist

    Project options showing Entitlements correctly set

  • (对于设备部署)应用 ID 已启用 SiriKit 并下载了预配配置文件。