添加 iOS App Extension
了解如何向 Flutter 应用添加 App Extension
本指南介绍如何在你的 Flutter 应用中使用 iOS App Extension。
概述
#iOS app extensions 让你能在 iOS 应用之外扩展功能。你的应用可以显示为主屏幕 widget,也可以让应用的部分功能在其他应用中可用。
在下面的示例中,当用户在 iOS「照片」应用中选择要分享的照片时,名为 Example App With Extension 的 Flutter 应用会出现在照片应用的分享表单中:
向 Flutter 应用添加 iOS App Extension
#
若要将 Flutter 应用与 iOS 操作系统集成,可以向 Flutter 项目添加 iOS App Extension。为便于操作,以下步骤演示如何向名为 example_app_with_extension 的新 Flutter 应用添加 Share
App Extension;你也可以从现有项目开始。
-
在控制台中,创建一个名为
example_app_with_extension的新 Flutter 项目。flutter create example_app_with_extension -
在控制台中,打开
example_app_with_extension项目的 Xcode 工作区。cd example_app_with_extension && open ios/Runner.xcworkspace -
在 Xcode 中,添加名为
Share的 App Extension,并将其命名为ShareExtension。在 Xcode 菜单栏中,选择 File > New > Target。
添加 Share Extension。
在 Name 字段中输入 ShareExtension。
点击 Finish。
在出现的 Activate … Scheme 对话框中,选择 Activate。
-
在 Xcode 中,调整构建过程的顺序。
打开 项目导航器(View > Navigators > Project)。
在 项目导航器 顶部,选择 Runner。
在主窗口的 TARGETS 下,选择 Runner。
打开 Build Phases 标签页。
将 Embed Foundation Extensions 拖到 Run Script 上方。
-
确保 Runner 与 ShareExtension 的 Minimum Deployments iOS 值已正确设置且一致
打开 项目导航器(View > Navigators > Project)。
在 项目导航器 顶部,选择 Runner。
在主窗口的 TARGETS 下,选择 Runner。
在 General 标签页中,检查 Minimum Deployments 下拉值是否与 ShareExtension > General 标签页中的值一致。
-
在控制台中,运行以下命令以重新构建 iOS 应用:
flutter build ios --config-only
添加新的 App Extension 时,Xcode 会根据所选模板生成示例代码。有关生成代码与 WidgetKit 的更多信息,请参阅 Apple 的 App Extension 文档。
测试 iOS App Extension
#向 Flutter 项目添加 App Extension 后,可使用模拟器或真机进行测试。若在 debug 模式下测试扩展,必须使用 iOS 模拟器。
以下步骤假定你使用的是 添加 iOS App Extension 中的示例应用与 Share 扩展。
-
在 Xcode 中,向项目添加 App Extension。
-
在控制台中,使用以下命令运行 iOS 应用:
flutter run -
在模拟器中测试 App Extension。
启动支持 Share 扩展的应用(例如「照片」应用)。
选择一张照片,点按分享按钮,再点按你应用的分享扩展图标。
向项目添加 App Extension。
-
在控制台中,以 release 模式运行 Flutter 应用:
flutter run --release -
在设备上测试 App Extension。
启动支持 Share 扩展的应用(例如「照片」应用)。
选择一张照片,点按分享按钮,再点按你应用的分享扩展图标。
与 iOS App Extension 交互的其他方式
#Flutter 应用与 iOS App Extension 的交互方式与 UIKit 或 SwiftUI 应用相同。宿主应用与 App Extension 不直接通信;用户在设备上与扩展交互时,宿主应用可能并未运行。应用与扩展可通过读写共享资源或使用更高级 API 相互通信。
使用更高级的 API
#部分扩展提供 API。例如,Core Spotlight 框架会为你的应用建立索引,使用户可从 Spotlight 和 Safari 搜索;WidgetKit 框架可触发主屏幕 widget 的更新。
为简化应用与扩展的通信,Flutter 插件封装了这些 API。要查找封装扩展 API 的插件,请参阅 利用 Apple 系统 API 与框架,或在 pub.dev 上搜索。
共享资源
#
要在 Flutter 应用与 App Extension 之间共享资源,将 Runner 应用 target 与扩展 target 置于同一 App Group
中。
要将 target 添加到 App Group:
在 Xcode 中打开 target 设置。
-
进入 Signing & Capabilities 标签页。
-
选择 + Capability,然后选择 App Groups。
-
从以下两种方式之一选择要添加 target 的 App Group:
从列表中选择一个 App Group。
点击 + 添加新的 App Group。
当两个 target 属于同一 App Group 时,它们可读写同一数据源。请为数据选择以下数据源之一:
-
键值对: 使用
shared_preference_app_group插件在同一 App Group 内读写UserDefaults。 -
文件: 使用
path_provider插件获取 App Group 容器路径,以 读写文件。 -
数据库: 使用
path_provider插件获取 App Group 容器路径,并用sqflite插件创建数据库。
安排后台更新
#后台任务让你能在应用处于任何状态时通过代码更新扩展。
要从 Flutter 应用安排后台工作,请使用 workmanager
插件。
添加深层链接
#你可能希望将用户从 App Extension 引导至 Flutter 应用中的特定页面。要在应用中打开特定路由,可使用 深层链接。
添加可滚动列表
#默认情况下,Share 扩展中的 Flutter 视图不处理滚动手势。若要在 Share 扩展中支持可滚动列表,请按 GitHub 上的说明 操作。
在 iOS App Extension 中打开 Flutter 应用
#
你可以通过 FlutterViewController 在某些 iOS App Extension(例如 Share
扩展)中直接打开 Flutter 应用。
在下面的示例中,名为 Example App With Extension 的 Flutter 应用在 Share 扩展中打开,用户可在应用间分享内容:
按以下步骤在 Share
App Extension 中显示 Flutter 应用。本示例中,
App Extension 的 scheme 为 ShareExtension,
Flutter 应用的 scheme 为 Runner,应用名为 Example App With Extension:
-
若尚未添加,请先 向 Flutter 应用添加扩展。
-
在控制台中,进入 Flutter 项目目录,然后用以下命令在 Xcode 中打开项目:
open ios/Runner.xcworkspace -
在 Xcode 中,禁用用户脚本沙盒(User Script Sandboxing)。
打开 项目导航器(View > Navigators > Project)。
在主窗口的 TARGETS 下,选择 ShareExtension。
打开 Build Settings 标签页。
找到 Build Options。
将 User Script Sandboxing 设为 No。
-
在 Xcode 中,为
ShareExtensionscheme 添加预操作 (pre-action)。打开 Manage Schemes 窗口(Product > Scheme > Manage Schemes)。
选择 ShareExtension scheme 并编辑。
展开 Build 标签页。
选择 Pre-actions。
点击 +,选择 New Run Script Action。
在 Provide build settings from 下拉列表中选择 ShareExtension。
在 Shell 文本框中输入:
/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" prepare点击 Close。
-
在 Xcode 中,共享构建配置。
打开 项目导航器(View > Navigators > Project)。
在主窗口的 PROJECT 下,选择 Runner。
打开 Info 标签页。
展开 Configuration。
展开 Debug,将 ShareExtension 的值更新为与 Runner 一致。
对 Profile 和 Release 重复上一步。
完成后,确认配置与下图类似:

-
(可选)如有需要,在 Xcode 中用扩展类替换 storyboard 文件。
打开 项目导航器(View > Navigators > Project)。
选择 Runner > ShareExtension > Info。
展开 Information Property List。
删除 NSExtensionMainStoryboard 键。
添加 NSExtensionPrincipalClass 键。
为
NSExtensionPrincipalClass键添加以下值之一:- (Swift) ShareExtension.ShareViewController
- (Objective-C) ShareViewController
-
在 Xcode 中,将
ShareViewController更新为使用FlutterViewController。打开 project navigator(View > Navigators > Project)。
选择 Runner > ShareExtension > ShareViewController。
将
ShareViewController更新为使用FlutterViewController类:
import UIKit
import Flutter
class ShareViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
showFlutter()
}
func showFlutter() {
let flutterEngine = FlutterEngine(name: "my flutter engine")
flutterEngine.run()
let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
addChild(flutterViewController)
view.addSubview(flutterViewController.view)
flutterViewController.view.frame = view.bounds
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.extensionContext?.cancelRequest(
withError: NSError(domain: Bundle.main.bundleIdentifier!, code: 0))
}
}
@import Flutter;
@import UIKit;
@interface ShareViewController : UIViewController
@end
#import "ShareViewController.h"
@import Flutter;
@implementation ShareViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self showFlutter];
}
- (void)showFlutter {
FlutterEngine *flutterEngine = [[FlutterEngine alloc] initWithName:@"my flutter engine"];
[flutterEngine run];
FlutterViewController *flutterViewController =
[[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];
[self addChildViewController:flutterViewController];
[self.view addSubview:flutterViewController.view];
flutterViewController.view.frame = self.view.bounds;
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.extensionContext cancelRequestWithError:[NSError errorWithDomain:NSBundle.mainBundle.bundleIdentifier code:0 userInfo:nil]];
}
@end
注册插件
#
按以下步骤为 App Extension 注册插件。本示例中,App Extension 的 scheme 为 ShareExtension,
Flutter 应用的 scheme 为 Runner,应用名为 Example App With Extension:
-
若尚未添加,请先 向 Flutter 应用添加扩展。
-
在 Xcode 中,将
GeneratedPluginRegistrant.m添加到 App Extension target。打开 project navigator(View > Navigators > Project)。
在主窗口的 TARGETS 下,选择 ShareExtension。
打开 Build Phases 标签页。
展开 Compile Sources。
点击 +。
在 Choose item to add 对话框的列表中选择 GeneratedPluginRegistrant.m。
点击 Add。
-
(仅 Swift)在 Xcode 中,更新
SWIFT_OBJC_BRIDGING_HEADER构建设置。打开 项目导航器(View > Navigators > Project)。
在主窗口的 TARGETS 下,选择 ShareExtension。
打开 Build Settings 标签页。
选择 All 筛选器。
找到 Swift Compiler - General,将 Objective-C Bridging Header 的值改为 Runner/Runner-Bridging-Header.h。
-
在 Xcode 中,更新
ShareViewController代码以注册GeneratedPluginRegistrant.h。打开 项目导航器(View > Navigators > Project)。
选择 Runner > ShareExtension > ShareViewController。
更新
ShareViewController文件以使用GeneratedPluginRegistrant.h:
// Add this inside `showFlutter()` at the top
GeneratedPluginRegistrant.register(with: flutterEngine)
// Add this import at the top
#import "GeneratedPluginRegistrant.h"
// Add this after [flutterEngine run]
[GeneratedPluginRegistrant registerWithRegistry:flutterEngine];
(Xcode) Test your app with the simulator.
(Xcode) 使用模拟器测试应用。
限制
#-
在 debug 模式下测试扩展时,必须使用 iOS 模拟器。
-
在真机上以 debug 模式构建扩展 UI 时,Flutter 对 App Extension 的支持并不完整,因为真机可能内存不足。
-
iOS App Extension 内存有限。建议仅在扩展至少支持 100MB 内存时才修改其 UI。
在 iOS App Extension 中调用 Dart 代码 / 渲染 Flutter 内容
#home_widget 插件提供大量功能,包括:
-
在 App Extension 中用 Dart 代码 响应用户输入。
-
在 App Extension 中将 Flutter widget 渲染 为图像。
-
在 iOS 上从
UserDefaults保存和读取数据。
其他资源
#要在 Flutter iOS 应用中使用 App Extension,请参阅 Codelab 向 Flutter 应用添加主屏幕 Widget。
要了解将 Flutter 界面添加到 iOS 应用的各种方式,请参阅 向 iOS 应用添加 Flutter 界面。
除非另有说明,本文档之所提及适用于 Flutter 3.44.0 版本。本页面最后更新时间:2026-06-15。查看文档源码 或者 为本页面内容提出建议。