为你的应用程序增加 AppIntent 能力
为你的应用程序增加AppIntent能力
引言
AppIntent是iOS16+之后引入的框架,在iOS17+后,对AppIntent的功能又进行了进一步的增强。其提供了接口可以让我们将应用程序的某部分特定功能抽离出来,提供给Siri和Shortcuts来进行调用。通过Siri和Shortcuts这类系统服务,用户的可以更加方便的使用App提供的便捷功能。另外AppIntent也可以和应用的小组件进行交互,增强小组件的交互能力。本篇文章,将讨论AppIntent的一些实用能力,希望可以对读者有所启发,将其应用于工程项目中。
一个简单的Shortcuts示例
只要我们在项目中定义了AppIntent的子类,那么系统的快捷指令服务就会自动的注册它,例如:
1 | struct CoffeeIntent: AppIntent { |
上面的代码直接写在应用的主工程中即可,无需做额外的处理,在系统的快捷指令中即可找到指令,如下:
执行此指令,会默认后台拉起我们的App,并执行CoffeeIntent中的perform方法,我们在其中执行要处理的逻辑即可,例如数据的处理,用户配置策略的更新等。AppIntent可以接收参数,在定义时,使用@Parameter来标记参数,在perform方法中可以对参数进行校验,如果不符合我们的要求,可以使用($参数名)内置对象调用needsValueError方法来弹出一个提示弹窗,让用户重新输入参数,效果如下:
可以看到,像系统的快捷指令中注册一个AppIntent非常简单。
AppIntent的配置介绍
AppIntent是一个协议,我们需要定义一个结构体来实现它。其中定义了一些get方法需要在结构体中提供,常用的包括:
title:设置此意图的标题。
description:设置此意图的描述信息。
openAppWhenRun:意图执行时,是否自动将应用拉起到前台。
authenticationPolicy:设置意图的执行权限,例如是否允许锁屏执行等。
isDiscoverable:设置是否能够被Shortcuts和Spotlight发现,默认为true,否则不能自动注册。
perform:具体的执行方法,实现此方法来执行具体逻辑。
在AppIntent执行时,默认会将应用在后台拉起,如果我们需要应用程序进入前台,需要设置openAppWhenRun为true。
上面的配置项都比较简单,我们着重看下perform函数,这个函数会默认在子线程处理,如果我们要进行UI操作,例如将AppIntent作为主应用的快捷入口,进行主应用的页面跳转或UI操作,则需要使用@MainActor进行标注,将其派发的主线程执行,如下:
1 | @MainActor |
另外,执行的结果需要返回一个实现了IntentResult的对象,因为perform方法被标记为了async,因此我们是可以在其中进行await的同步编程,等待耗时任务结束后再返回结果。上面示例代码中,返回了一个空的结果,表示执行成功。我们也可以返回一个自定义的Dialog来展示执行的结果,如下:
1 | @MainActor |
效果如下图:
需要注意,返回的IntentResult实例要和perform函数的返回值一致,对于Dialog类型的结果,我们甚至可以通过一个简单的SwiftUI视图来自定义内容。
AppIntent也支持进行链式的调用,例如:
1 | struct CoffeeIntent: AppIntent { |
上面的代码,当执行完成CoffeeIntent的逻辑后,会再执行TeaIntent的逻辑。
向系统搜索服务中注册Shortcuts
在iOS17后,可以向系统的搜索服务中注册核心的Shortcuts,对于这类Shortcuts,用户无需手动添加,即可在搜索服务入口处直接调用。需要定义一个结构体来实现AppShortcutsProvider协议,例如:
1 | struct ShortcutsManager: AppShortcutsProvider { |
AppShortcutsProvide会注册一组核心的AppIntent,之后可以在搜索和快捷指令中找到这些核心的AppIntent直接使用,如下:
另外,如果需要对注册的这些Intent进行更新,则直接调用此方法即可:
1 | ShortcutsManager.updateAppShortcutParameters() |
一些补充
在上面的示例中,在构建AppShortcut时可以设置一个系统图片,要想知道有哪些可用的图标,可以在下面的地址中下载SF-SYMBOLS应用,其中会将所有支持的符号与对应的名称列出。