搜索插件、代码仓与 APP 分类

插件详情v0.2.0

intelligence

Apple 的 AppIntent 集成插件。让您的应用被 Siri、快捷指令应用、Apple Intelligence 等理解。

iOS
近 30 天下载
1.1万
喜欢数
51
Pub 分数
140

安装插件

flutter pub add intelligence

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

智能包是一个Flutter插件,可让iOS应用集成Apple的AppIntents框架,从而与Siri、快捷指令应用和Apple Intelligence进行更深入的交互。它允许用户通过语音命令或快捷指令触发应用操作,提升可访问性和自动化能力。该插件通过提供Dart级别的API来定义意图、参数和结果,简化了将应用功能暴露给Apple生态系统的流程。该插件专为iOS设计,需要遵循Apple的AppIntents指南。

适合场景

  • 启用Siri语音命令以执行应用操作
  • 与快捷指令应用集成
  • 支持 Apple Intelligence 功能
  • 允许用户自动化任务
  • 提升应用在苹果生态系统中的可发现性

主要特点

  • 无缝集成 Apple AppIntents
  • 用于定义意图的 Dart API
  • 支持 Siri 和快捷指令
  • 仅限iOS平台兼容性
  • 使用 Flutter pub add 轻松设置

适合对象

  • 面向 Apple Intelligence 的 iOS 开发者
  • 需要语音命令支持的应用程序
  • 面向自动化的应用程序
  • 在 iOS 上使用 Flutter 的开发者
  • 旨在实现更深层次 Siri 集成的应用程序

使用建议

  • 需要 iOS 17 或更高版本
  • 仅限苹果生态系统
  • 需要在 Xcode 中配置 AppIntents
  • 不兼容 Android
  • 取决于 Apple 不断发展的 AppIntents 框架

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

Intelligence

MIT license PRs Welcome Monterail's logo

Add support for Apple's AppIntents framework to your Flutter application. For details on how to add integration with Siri, Shortcuts app, and Apple Intelligence, see Recipes.

Installation

Copy and paste the following snippet into your shell when in the target project directory.

dart pub add intelligence

Usage

To add support for AppIntents framework, you will have to perform one-time setup which differs for different use-cases. See Recipes for more details.

iOS Configuration

After installing the package, you need to set the minimum iOS version to 16.0 on XCode.

For more details, follow these steps:

  • Open the iOS project in Xcode

    Open in Xcode
  • Click on Runner & then general tab

    Runner & general tab

  • Under the General tab & minimum deployments section, set the iOS version to atleast 16.0 iOS version


Once set up, the plugin will let you act on each App Intent trigger.

E.g. while setting the selection listener in a Stateful widget:

Intelligence().selectionsStream().listen(_handleSelection);

Note: the Intelligence class behaves like a singleton, so you do not have to maintain the same class instance throughout the app/use-case.

Recipes

List of practical applications of intelligence in your project. Click the Details dropdown to see the implementation.

Allow the Shortcuts app to open a specific page in your application

Will let your app to be automated via Shortcuts workflow.

  • Open the iOS project in Xcode
Open in Xcode
  • Add a new Swift file and paste:
import AppIntents
import intelligence

struct OpenHeartIntent: AppIntent {
  static var title: LocalizedStringResource = "Draw a Heart"
  static var openAppWhenRun: Bool = true
  
  @MainActor
  func perform() async throws -> some IntentResult {
    IntelligencePlugin.notifier.push("heart")
    return .result()
  }
}

Switch out the struct's name, title, and the .pushed value to ones that match your use-case.

Once added, your App Intent will show up in the Shortcuts app:

Example of a Shortcuts app workflow including an automation step declared in this guide
Optionally: Add a Siri voice shortcut to for the App Intent

To trigger the App Intent declared above by speaking a specific phrase to Siri, append:

struct OpenHeartShortcuts: AppShortcutsProvider {
  static var appShortcuts: [AppShortcut] {
    AppShortcut(
      intent: ExampleAppIntent(),
      phrases: [
        "Draw my favorite shape in \(.applicationName)"
      ]
    )
  }
}

Once deployed to the device, Siri can understand the trigger phrase and run the App Intent declared above:

Siri's response to a query 'What can Intelligence do?' including defined phrase to run the App Intent declared in this guide
Let Siri open a specific entity from your app domain

Siri is capable of understanding the entities your application revolves around, letting you implement App Intents with variables.

See full implementation in the example project.

  • Define an AppEntity. It should contain a unique identifier and a text representation fields, as follows:
import CoreSpotlight
import AppIntents

struct RepresentableEntity: AppEntity {
  static var defaultQuery: RepresentableQuery = RepresentableQuery()
  static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Shape")
  
  var displayRepresentation: DisplayRepresentation {
    DisplayRepresentation(stringLiteral: representation)
  }
  
  let id: String
  let representation: String
}

extension RepresentableEntity: IndexedEntity {
  var attributeSet: CSSearchableItemAttributeSet {
    let attributes = CSSearchableItemAttributeSet()
    attributes.displayName = self.representation
    return attributes
  }
}
  • Create a matching EntityQuery, like so:
import AppIntents
import intelligence

struct RepresentableQuery: EntityQuery {
  func entities(for identifiers: [String]) async throws -> [RepresentableEntity] {
    return IntelligencePlugin.storage.get(for: identifiers).map() { item in
      return RepresentableEntity(
        id: item.id,
        representation: item.representation
      )
    }
  }
  
  func suggestedEntities() async throws -> [RepresentableEntity] {
    return IntelligencePlugin.storage.get().map() { item in
      return RepresentableEntity(
        id: item.id,
        representation: item.representation
      )
    }
  }
}

extension RepresentableQuery: EnumerableEntityQuery {
  func allEntities() async throws -> [RepresentableEntity] {
    return IntelligencePlugin.storage.get().map() { item in
      return RepresentableEntity(
        id: item.id,
        representation: item.representation
      )
    }
  }
}
  • Create an AppIntent using the entity as a parameter.
import AppIntents
import intelligence

struct ExampleAppIntent: AppIntent {
  static var title: LocalizedStringResource = "Draw shape"
  static var openAppWhenRun: Bool = true
    
  @Parameter(title: "Shape")
  var target: RepresentableEntity
  
  @MainActor
  func perform() async throws -> some IntentResult {
    IntelligencePlugin.notifier.push(target.id)
    return .result()
  }
  
  static var parameterSummary: some ParameterSummary {
    Summary("Draw \(\.$target)")
  }
}


struct AppShortcuts: AppShortcutsProvider {
  static var appShortcuts: [AppShortcut] {
    AppShortcut(
      intent: ExampleAppIntent(),
      phrases: [
        "Draw a \(\.$target) in \(.applicationName)"
      ]
    )
  }
}

  • In your AppDelegate file, add the following code to the didFinishLaunchingWithOptions method:
  IntelligencePlugin.storage.attachListener {
    AppShortcuts.updateAppShortcutParameters()
  }
  if #available(iOS 18.0, *) {
    IntelligencePlugin.spotlightCore.attachEntityMapper() { item in
      return RepresentableEntity(
        id: item.id,
        representation: item.representation
      )
    }
  }
  • In your Dart code, use the .populate method to let the operating system know about the entities available in your app:
await IntelligencePlugin().populate(const [
  Representable(representation: 'Heart', id: 'heart'),
  Representable(representation: 'Circle', id: 'circle'),
  Representable(representation: 'Rectangle', id: 'rectangle'),
  Representable(representation: 'Triangle', id: 'triangle'),
]);

Note: each call to .populate overwrites previous entities. Call .populate([]) once the entities are not accessible anymore, e.g. after a logout.

Result:

Siri query usage example

Further reading

所属分类

依赖

依赖清单 4 项

源码仓库

使用此插件的项目