写点什么

为你的应用程序增加 AppIntent 能力

作者:珲少
  • 2024-05-28
    上海
  • 本文字数:2890 字

    阅读完需:约 9 分钟

为你的应用程序增加 AppIntent 能力

引言

AppIntent 是 iOS16+之后引入的框架,在 iOS17+后,对 AppIntent 的功能又进行了进一步的增强。其提供了接口可以让我们将应用程序的某部分特定功能抽离出来,提供给 Siri 和 Shortcuts 来进行调用。通过 Siri 和 Shortcuts 这类系统服务,用户的可以更加方便的使用 App 提供的便捷功能。另外 AppIntent 也可以和应用的小组件进行交互,增强小组件的交互能力。本篇文章,将讨论 AppIntent 的一些实用能力,希望可以对读者有所启发,将其应用于工程项目中。

一个简单的 Shortcuts 示例

只要我们在项目中定义了 AppIntent 的子类,那么系统的快捷指令服务就会自动的注册它,例如:


struct CoffeeIntent: AppIntent {    static var title = LocalizedStringResource("接收用户输入")    static var description = IntentDescription("接收用户输入的测试Intent")        // 定义参数    @Parameter(title:"输入")    var type: String?
func perform() async throws -> some IntentResult { guard let type, type.count > 3 else { throw $type.needsValueError(.init("参数太短")) } print("处理逻辑部分") return .result() }}
复制代码


上面的代码直接写在应用的主工程中即可,无需做额外的处理,在系统的快捷指令中即可找到指令,如下:



执行此指令,会默认后台拉起我们的 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 进行标注,将其派发的主线程执行,如下:


    @MainActor    func perform() async throws -> some IntentResult {        guard let type, type.count > 3 else {            throw $type.needsValueError(.init("参数太短"))        }        print("处理逻辑部分")        return .result()    }
复制代码


另外,执行的结果需要返回一个实现了 IntentResult 的对象,因为 perform 方法被标记为了 async,因此我们是可以在其中进行 await 的同步编程,等待耗时任务结束后再返回结果。上面示例代码中,返回了一个空的结果,表示执行成功。我们也可以返回一个自定义的 Dialog 来展示执行的结果,如下:


    @MainActor    func perform() async throws -> some ProvidesDialog & ShowsSnippetView {        guard let type, type.count > 3 else {            throw $type.needsValueError(.init("参数太短"))        }        print("处理逻辑部分")        return .result(dialog: .init("Dialog标题")) {            VStack(spacing: 10) {                Text("自定义的弹窗内容")                Text("自定义的弹窗内容")                Text("自定义的弹窗内容")            }        }    }
复制代码


效果如下图:



需要注意,返回的 IntentResult 实例要和 perform 函数的返回值一致,对于 Dialog 类型的结果,我们甚至可以通过一个简单的 SwiftUI 视图来自定义内容。


AppIntent 也支持进行链式的调用,例如:


struct CoffeeIntent: AppIntent {    static var title = LocalizedStringResource("接收用户输入")    static var description = IntentDescription("接收用户输入的测试Intent")        // 定义参数    @Parameter(title:"输入")    var type: String?
@MainActor func perform() async throws -> some OpensIntent { guard let type, type.count > 3 else { throw $type.needsValueError(.init("参数太短")) } print("处理逻辑部分") return .result(opensIntent: TeaIntent()) }}
struct TeaIntent: AppIntent { static var title = LocalizedStringResource("无用户输入") static var description = IntentDescription("无用户输入的Intent")
@MainActor func perform() async throws -> some IntentResult { print("链式处理逻辑部分") return .result() }}
复制代码


上面的代码,当执行完成 CoffeeIntent 的逻辑后,会再执行 TeaIntent 的逻辑。

向系统搜索服务中注册 Shortcuts

在 iOS17 后,可以向系统的搜索服务中注册核心的 Shortcuts,对于这类 Shortcuts,用户无需手动添加,即可在搜索服务入口处直接调用。需要定义一个结构体来实现 AppShortcutsProvider 协议,例如:


struct ShortcutsManager: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] { AppShortcut( intent: CoffeeIntent(), phrases: [ "\(.applicationName)搜索" ], shortTitle: "搜索", systemImageName: "magnifyingglass" ) AppShortcut( intent: CoffeeIntent(), phrases: [ "\(.applicationName)编辑" ], shortTitle: "编辑", systemImageName: "square.and.pencil" ) AppShortcut( intent: CoffeeIntent(), phrases: [ "\(.applicationName)二维码" ], shortTitle: "二维码", systemImageName: "qrcode.viewfinder" ) }}
复制代码


AppShortcutsProvide 会注册一组核心的 AppIntent,之后可以在搜索和快捷指令中找到这些核心的 AppIntent 直接使用,如下:




另外,如果需要对注册的这些 Intent 进行更新,则直接调用此方法即可:


 ShortcutsManager.updateAppShortcutParameters()
复制代码

一些补充

在上面的示例中,在构建 AppShortcut 时可以设置一个系统图片,要想知道有哪些可用的图标,可以在下面的地址中下载 SF-SYMBOLS 应用,其中会将所有支持的符号与对应的名称列出。


https://developer.apple.com/sf-symbols/

发布于: 刚刚阅读数: 4
用户头像

珲少

关注

还未添加个人签名 2022-07-26 加入

还未添加个人简介

评论

发布
暂无评论
为你的应用程序增加AppIntent能力_珲少_InfoQ写作社区