跳转至正文

将 Flutter 应用集成到 iOS 项目

了解如何将 Flutter 应用集成到你现有的 iOS 项目中。

你可以使用 Swift package 将 Flutter UI 组件逐步添加到你现有的 iOS 应用中。

前提条件

#
  • Flutter 3.44 或更高版本

  • Xcode 15.0 或更高版本

从旧版集成方式迁移(如适用)

#

如果你已经使用 CocoaPods 或嵌入式 framework 将 Flutter 集成到 iOS 应用中,则必须先移除该集成,再按照下面的 Swift Package Manager 说明操作。

展开查看从 CocoaPods 集成迁移的说明

如果你的应用之前是通过 CocoaPods 集成的,则必须先从 Podfile 中移除 Flutter 安装代码。

  1. 从 Podfile 中移除 Flutter 安装代码。

    MyApp/Podfile
    ruby
    flutter_application_path = '../my_flutter'
    load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
    
    install_all_flutter_pods(flutter_application_path)
    
    flutter_post_install(installer) if defined?(flutter_post_install)
    
  2. 运行 pod install

展开查看从嵌入式 framework 集成迁移的说明

如果你的应用之前是通过 flutter build ios-framework 命令生成的 framework 集成的,则必须先从 Xcode 项目中移除这些 framework。

  1. 进入 target 的 General 标签页,在 Frameworks, Libraries, and Embedded Content(框架、库与嵌入内容)下移除所有与 Flutter 相关的 framework 和库。

    这包括 App.xcframeworkFlutter.xcframeworkFlutterPluginRegistrant.xcframework,以及所有 Flutter 插件的 xcframework 文件。

  2. 从 Podfile 中移除 Flutter pod。

    MyApp/Podfile
    ruby
    pod 'Flutter', :podspec => '/path/to/MyApp/Flutter/[build mode]/Flutter.podspec'
    
  3. 运行 pod install

旧版集成指南 仍保留以供参考,但不再持续维护。

组织各项目的相对位置

#

本指南假定你现有的 iOS 应用与你的 Flutter 应用或模块位于同级目录中。如果你的目录结构不同,则需要相应地调整示例中的相对路径。

示例目录结构如下所示:

  • my_flutter_app/
    • ios/
    • lib/
      • main.dart
  • MyNativeApp/
    • MyNativeApp.xcodeproj/
  • my_flutter_app/
    • .ios/
    • lib/
      • main.dart
  • MyNativeApp/
    • MyNativeApp.xcodeproj/

使用 Swift Package Manager 集成

#
  1. 构建 FlutterNativeIntegration Swift package

    在你的 Flutter 应用或模块中,运行以下命令:

    flutter build swift-package --platform ios
    

    这会生成以下目录:

    • my_flutter_app/build/ios/SwiftPackages/
      • FlutterNativeIntegration/(A Swift package)
      • Scripts/(Directory of scripts and other files needed)

    你也可以通过 --output 标志更改此输出的位置。

  2. 将 FlutterNativeIntegration 添加到你的 Xcode 项目

    1. 在 Xcode 中打开你现有的 iOS 应用。

    2. 在 Project navigator(项目导航器)中右键点击你的项目,选择 Add Files to "MyNativeApp"...(向 "MyNativeApp" 添加文件…)。

    3. 定位并选择生成的 FlutterNativeIntegration Swift package,然后点击 Add(添加)。

    4. 选择 Reference files in place(在原位置引用文件),然后点击 Finish(完成)。

    5. 在 File inspector(文件检查器)中,确认 Location(位置)为 Relative to Project(相对于项目)。如果不是,则需要将 Flutter 输出目录移动为与原生应用同级的目录。

      Relative location of FlutterNativeIntegration shown in Xcode's File inspector.

      Relative location of FlutterNativeIntegration shown in Xcode's File inspector.

    6. 进入 target 的 General(通用)标签页,在 Frameworks, Libraries, and Embedded Content(框架、库与嵌入内容)下添加 FlutterNativeIntegration

      FlutterNativeIntegration under Frameworks, Libraries, and Embedded Content.

      FlutterNativeIntegration under Frameworks, Libraries, and Embedded Content.

  3. 添加构建设置

    1. In the Build Settings tab, set the location of the Flutter app's Swift package output directory:

      FLUTTER_SWIFT_PACKAGE_OUTPUT=$SRCROOT/../my_flutter_app/build/ios/SwiftPackages
      

      Build Settings(构建设置)标签页中,设置 Flutter 应用的 Swift package 输出目录的位置:

      FLUTTER_SWIFT_PACKAGE_OUTPUT=$SRCROOT/../my_flutter_app/build/ios/SwiftPackages
      
    2. 对于自定义配置,请设置 Flutter 构建模式。

      Flutter 支持三种 构建模式:Debug、Profile 和 Release。构建模式由 CONFIGURATION 决定。如果你的配置与其中任何一个都不匹配,可以将 FLUTTER_BUILD_MODE 构建设置设为这些值之一。

      Setting `FLUTTER_BUILD_MODE` for custom configurations under **Build Settings**.

      Setting FLUTTER_BUILD_MODE for custom configurations under Build Settings.

    3. (可选)允许 Xcode 重新构建你的 Flutter 应用。

      将以下构建设置添加到你的 target,以允许 Xcode 在其构建过程中重新构建你的 Flutter 应用。这样你就可以更改 Flutter 应用,而无需重新运行 flutter build swift-package。这需要机器上已安装 Flutter。

      FLUTTER_APPLICATION_PATH=$SRCROOT/../my_flutter_app
      ENABLE_USER_SCRIPT_SANDBOXING=NO
      
  4. 向 Scheme 添加 Pre-action 运行脚本

    1. 打开 Product > Scheme > Edit Scheme... > Build(左侧边栏)> Pre-action > + > New Run Script Action

    2. Provide build settings from(提供构建设置来源)下拉菜单中选择你的项目。

    3. 将脚本设为以下内容:

      /bin/sh $FLUTTER_SWIFT_PACKAGE_OUTPUT/Scripts/flutter_integration.sh prebuild
      
    Pre-action Run Script in scheme editor.

    Pre-action Run Script in scheme editor.

  5. 向 Target 添加新的运行脚本构建阶段

    1. 进入你的 target 的 Build Phases(构建阶段) > + > New Run Script Phase

    2. 将脚本设为以下内容:

      /bin/sh $FLUTTER_SWIFT_PACKAGE_OUTPUT/Scripts/flutter_integration.sh assemble
      
    3. 取消勾选 Based on dependency analysis(基于依赖分析)。

    4. 将以下内容添加到 Input File Lists(输入文件列表):

      $(FLUTTER_SWIFT_PACKAGE_OUTPUT)/Scripts/FlutterAssembleInputs.xcfilelist
      
    New Run Script Build Phase under Build Phases.

    New Run Script Build Phase under Build Phases.

  6. (可选)设置 LLDB Init File

    在 iOS 26+ 真机上调试时,使用 Flutter 的 LLDB Init File 可以提升性能。

    1. 打开 Product > Scheme > Edit Scheme... > Run(左侧边栏)。

    2. LLDB Init File 设为以下路径:

      $(FLUTTER_SWIFT_PACKAGE_OUTPUT)/Scripts/flutter_lldbinit
      

      或者,如果你的 scheme 已经有 LLDB Init File,可以将 Flutter 的 LLDB 文件添加进去。 Flutter 的 LLDB Init File 的路径必须相对于你项目的 LLDB Init File 的位置。

      command source --relative-to-command-file "../my_flutter_app/build/ios/SwiftPackages/Scripts/flutter_lldbinit"
      

设置本地网络隐私权限

#

在 iOS 14 及更高版本上,请在 iOS app 的 Debug 版本中启用 Dart 多播 DNS 服务。这样可通过 flutter attach 使用热重载和 DevTools 等调试功能

若仅在 app 的 Debug 版本中设置本地网络隐私权限,请为每个构建配置创建单独的 Info.plist。 SwiftUI 项目一开始可能没有 Info.plist 文件。如需创建属性列表,可通过 Xcode 或文本编辑器完成。以下说明假定使用默认的 DebugRelease。请根据 app 的构建配置按需调整名称。

  1. 创建新的属性列表。

    1. 在 Xcode 中打开项目。

    2. Project Navigator 中点击项目名称。

    3. 在编辑器窗格的 Targets 列表中点击你的 app。

    4. 点击 Info 标签页。

    5. 展开 Custom iOS Target Properties

    6. 右键点击列表,选择 Add Row

    7. 在下拉菜单中选择 Bonjour Services。这会在项目目录中创建一个名为 Info 的新属性列表。在 Finder 中显示为 Info.plist

  2. Info.plist 重命名为 Info-Debug.plist

    1. 在左侧项目列表中点击 Info 文件。

    2. 在右侧 Identity and Type 面板中,将 NameInfo.plist 改为 Info-Debug.plist

  3. 创建 Release 属性列表。

    1. Project Navigator 中点击 Info-Debug.plist

    2. 选择 File > Duplicate...。也可按 Cmd + Shift + S

    3. 在对话框中将 Save As: 设为 Info-Release.plist,然后点击 Save

  4. Debug 属性列表添加必要属性。

    1. Project Navigator 中点击 Info-Debug.plist

    2. Bonjour Services 数组添加字符串值 _dartVmService._tcp

    3. (可选) 若要设置自定义权限对话框文案,请添加键 Privacy - Local Network Usage Description

      The `Info-Debug` property list with the **Bonjour Services** and **Privacy - Local Network Usage Description** keys added

      The Info-Debug property list with the Bonjour Services and Privacy - Local Network Usage Description keys added

  5. 设置 target 在不同构建模式下使用不同属性列表。

    1. Project Navigator 中点击你的项目。

    2. 点击 Build Settings 标签页。

    3. 点击 AllCombined 子标签页。

    4. 在搜索框中输入 plist,将设置限定为与属性列表相关的项。

    5. 滚动列表直至看到 Packaging

    6. 点击 Info.plist File 设置。

    7. Info.plist File 的值从 path/to/Info.plist 改为 path/to/Info-$(CONFIGURATION).plist

      Updating the `Info.plist` build setting to use build mode-specific property lists

      Updating the Info.plist build setting to use build mode-specific property lists

      Debug 中解析为 Info-Debug.plist,在 Release 中解析为 Info-Release.plist

      The updated **Info.plist File** build setting displaying the configuration variations

      The updated Info.plist File build setting displaying the configuration variations

  6. Build Phases 中移除 Release 属性列表。

    1. Project Navigator 中点击你的项目。

    2. 点击 Build Phases 标签页。

    3. 展开 Copy Bundle Resources

    4. 若列表包含 Info-Release.plist,请点击它,再点击下方 -(减号)将其从资源列表中移除。

      The **Copy Bundle** build phase displaying the **Info-Release.plist** setting. Remove this setting.

      The Copy Bundle build phase displaying the Info-Release.plist setting. Remove this setting.

  7. Debug app 加载的第一个 Flutter 界面会提示本地网络权限。

    点击 OK

    (可选) 若要在 app 加载前授予权限,请启用 Settings > Privacy > Local Network > Your App

后续步骤

#

现在你可以向现有的 iOS 应用 添加 Flutter 页面 了。