-
Notifications
You must be signed in to change notification settings - Fork 30.1k
Description
Design
To support SwiftPM plugins in add-to-app, we plan to introduce a new command that creates a swift package (called FlutterPluginRegistrant) that can be added to a native iOS or macOS Xcode project.
The FlutterPluginRegistrant will have dependencies on Flutter plugins, the Flutter framework, and the Flutter App framework.
- Flutter plugin that support SwiftPM will be copied from the pubcache to the output directory. If the plugin does not have a dependency on the Flutter framework, we'll add the dependency using
swift packagecommands. - Flutter plugins that support CocoaPods only will be built into xcframeworks in the output directory.
- The Flutter framework will be copied from the engine artifacts or use a remote url (if requested via flag).
- The App framework will be built into an xcframework in the output directory.
To handle different frameworks per build mode, we'll utilize symlinks and build scripts to swap the correct artifacts.
Build configuration will be handled via symlinks (see Sources and Package.swift in file structure below)
├── FlutterPluginRegistrant
│ ├── Debug
│ │ ├── FlutterPluginRegistrant (module source files)
│ │ ├── Frameworks
│ │ │ ├── App.xcframework
│ │ │ ├── CocoaPods
│ │ │ │ ├── [CocoaPods-only Flutter plugins build into xcframeworks]
│ │ │ ├── Flutter.xcframework
│ │ │ ├── NativeAssets
│ │ │ │ ├── [NativeAssets Flutter plugins build into xcframeworks]
│ │ ├── Package.swift
│ │ ├── Packages
│ │ │ ├── for each plugin -> symlink to ../../../Plugins/[plugin_name]
│ │ │ ├── FlutterFramework
│ ├── Release
│ ├── Sources -> symlink to ./Debug
│ ├── Package.swift -> symlink to ./Debug/Package.swift
├── FlutterConfigurationPlugin
├── Plugins
│ ├── [Copied Flutter plugins that support SwiftPM]
├── Scripts
│ ├── pre_action.sh
│ ├── post_embed.sh
let package = Package(
name: "FlutterPluginRegistrant",
products: [
.library(name: "FlutterPluginRegistrant", type: .static, targets: ["FlutterPluginRegistrant"])
],
dependencies: [
.package(name: "FlutterFramework", path: "Sources/Packages/FlutterFramework"),
.package(name: "plugin_with_swiftpm_support", path: "Sources/Packages/plugin_with_swiftpm_support"),
.package(name: "FlutterConfigurationPlugin", path: "../FlutterConfigurationPlugin")
],
targets: [
.target(
name: "FlutterPluginRegistrant",
dependencies: [
.product(name: "FlutterFramework", package: "FlutterFramework"),
.target(name: "App"),
.product(name: "plugin-with-swiftpm-support", package: "plugin_with_swiftpm_support"),
.target(name: "cocoapod_only_plugin"),
.target(name: "native_asset_plugin")
]
),
.binaryTarget(
name: "App",
path: "Sources/Frameworks/App.xcframework"
),
.binaryTarget(
name: "cocoapod_only_plugin",
path: "Sources/Frameworks/CocoaPods/cocoapod_only_plugin.xcframework"
),
.binaryTarget(
name: "native_asset_plugin",
path: "Sources/Frameworks/NativeAssets/native_asset_plugin.xcframework"
)
]
)When integrating into the existing Xcode project a script will need to be added to the scheme's Pre-Action to swap the FlutterPluginRegistrant/Sources and FlutterPluginRegistrant/Package.swift symlink to the appropriate build mode.
Another script will be added as a Build Phase (after embedding), which will validate that the correct artifacts are embedded for the targeted build configuration as a safeguard. It will also run flutter assemble if FLUTTER_APPLICATION_PATH is set. This will re-build the App.framework with any Dart code changes.
In addition, we will also provide a swift package plugin (FlutterConfigurationPlugin), which will allow the developer to manually switch the build mode via Xcode's GUI.
Implementation Plan
See subtasks