Flutter UI 组件可以作为嵌入式框架逐步添加到现有 iOS 应用程序中。要将 Flutter 嵌入到现有应用程序中,请考虑以下三种方法之一。

嵌入方法方法论优势
使用 CocoaPods (推荐)安装并使用 Flutter SDK 和 CocoaPods。每次 Xcode 构建 iOS 应用时,Flutter 都会从源代码编译 flutter_module将 Flutter 嵌入到你的应用中最简单的方法。
使用 iOS 框架为 Flutter 组件创建 iOS 框架,将其嵌入到你的 iOS 应用中,并更新现有应用的构建设置。无需每位开发者都在本地机器上安装 Flutter SDK 和 CocoaPods。
使用 iOS 框架和 CocoaPods在 Xcode 中嵌入 iOS 应用的框架和插件,但将 Flutter 引擎作为 CocoaPods podspec 进行分发。提供了一种替代方案,用于分发大型 Flutter 引擎 (Flutter.xcframework) 库。

将 Flutter 添加到现有 iOS 应用时,它会增加你的 iOS 应用的大小

有关使用 UIKit 构建的应用示例,请参阅 add_to_app 代码示例中的 iOS 目录。有关使用 SwiftUI 的示例,请查阅 News Feed App 中的 iOS 目录。

开发系统要求

#

Flutter 需要最新版本的 Xcode 和 CocoaPods

创建 Flutter 模块

#

要通过任何方法将 Flutter 嵌入到现有应用程序中,请首先创建一个 Flutter 模块。使用以下命令创建 Flutter 模块。

cd /path/to/my_flutter
flutter create --template module my_flutter

Flutter 会在 /path/to/my_flutter/ 下创建模块项目。如果你使用 CocoaPods 方法,请将模块保存在与现有 iOS 应用相同的父目录中。

在 Flutter 模块目录中,你可以运行任何其他 Flutter 项目中相同的 flutter 命令,例如 flutter runflutter build ios。你还可以使用 Flutter 和 Dart 插件在 VS CodeAndroid Studio/IntelliJ 中运行该模块。此项目包含你的模块的单视图示例版本,然后再将其嵌入到现有 iOS 应用中。这有助于测试代码中仅限 Flutter 的部分。

组织你的模块

#

my_flutter 模块目录结构类似于典型的 Flutter 应用。

my_flutter/
├── .ios/
│   ├── Runner.xcworkspace
│   └── Flutter/podhelper.rb
├── lib/
│   └── main.dart
├── test/
└── pubspec.yaml

你的 Dart 代码应添加到 lib/ 目录中。你的 Flutter 依赖项、包和插件必须添加到 pubspec.yaml 文件中。

隐藏的 .ios/ 子文件夹包含一个 Xcode 工作区,你可以在其中运行模块的独立版本。这个包装项目引导你的 Flutter 代码。它包含辅助脚本,以便于构建框架或使用 CocoaPods 将模块嵌入到现有应用程序中。

将 Flutter 模块嵌入到你的 iOS 应用中

#

开发完 Flutter 模块后,你可以使用页面顶部表格中描述的方法来嵌入它。

你可以在模拟器或真机上以调试模式运行,在真机上以发布模式运行。

使用 CocoaPods 和 Flutter SDK

#

方法

#

第一种方法使用 CocoaPods 嵌入 Flutter 模块。CocoaPods 管理 Swift 项目的依赖项,包括 Flutter 代码和插件。每次 Xcode 构建应用时,CocoaPods 都会嵌入 Flutter 模块。

这允许在不运行 Xcode 之外的额外命令的情况下,使用最新版本的 Flutter 模块进行快速迭代。

要了解更多关于 CocoaPods 的信息,请查阅 CocoaPods 入门指南

观看视频

#

如果观看视频有助于你学习,此视频涵盖了将 Flutter 添加到 iOS 应用的内容

在新标签页中观看 YouTube 视频:“如何在现有 iOS 应用中逐步添加 Flutter”

要求

#

项目中的每位开发者都必须安装 Flutter SDK 和 CocoaPods 的本地版本。

项目结构示例

#

本节假设你的现有应用和 Flutter 模块位于同级目录中。如果你有不同的目录结构,请调整相对路径。示例目录结构如下所示

/path/to/MyApp
├── my_flutter/
│   └── .ios/
│       └── Flutter/
│         └── podhelper.rb
└── MyApp/
    └── Podfile

更新你的 Podfile

#

将你的 Flutter 模块添加到 Podfile 配置文件中。本节假定你将 Swift 应用命名为 MyApp

  1. (可选)如果你的现有应用缺少 Podfile 配置文件,请导航到你的应用目录的根目录。使用 pod init 命令创建 Podfile 文件。

  2. 更新你的 Podfile 配置文件。

    1. platform 声明之后添加以下行。

      MyApp/Podfile
      ruby
      flutter_application_path = '../my_flutter'
      load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
    2. 对于需要嵌入 Flutter 的每个 Podfile 目标,添加对 install_all_flutter_pods(flutter_application_path) 方法的调用。在前面步骤的设置之后添加这些调用。

      MyApp/Podfile
      ruby
      target 'MyApp' do
        install_all_flutter_pods(flutter_application_path)
      end
    3. Podfilepost_install 块中,添加对 flutter_post_install(installer) 的调用。此块应是 Podfile 配置文件中的最后一个块。

      MyApp/Podfile
      ruby
      post_install do |installer|
        flutter_post_install(installer) if defined?(flutter_post_install)
      end

要查看 Podfile 示例,请查阅此Flutter Podfile 示例

嵌入你的框架

#

在构建时,Xcode 将你的 Dart 代码、每个 Flutter 插件和 Flutter 引擎打包到它们各自的 *.xcframework 包中。然后,CocoaPod 的 podhelper.rb 脚本将这些 *.xcframework 包嵌入到你的项目中。

  • Flutter.xcframework 包含 Flutter 引擎。
  • App.xcframework 包含此项目的编译 Dart 代码。
  • <plugin>.xcframework 包含一个 Flutter 插件。

要将 Flutter 引擎、你的 Dart 代码和 Flutter 插件嵌入到你的 iOS 应用中,请完成以下步骤。

  1. 刷新你的 Flutter 插件。

    如果你更改了 pubspec.yaml 文件中的 Flutter 依赖项,请在 Flutter 模块目录中运行 flutter pub get。这会刷新 podhelper.rb 脚本读取的插件列表。

    flutter pub get
  2. 使用 CocoaPods 嵌入插件和框架。

    1. 导航到你的 iOS 应用项目,路径为 /path/to/MyApp/MyApp

    2. 使用 pod install 命令。

      pod install

    你的 iOS 应用的调试发布构建配置会嵌入该构建模式对应的 Flutter 组件

  3. 构建项目。

    1. 在 Xcode 中打开 MyApp.xcworkspace

      验证你打开的是 MyApp.xcworkspace 而不是 MyApp.xcodeproj.xcworkspace 文件包含 CocoaPod 依赖项,而 .xcodeproj 不包含。

    2. 选择Product > Build 或按下 Cmd + B

设置 LLDB Init File

#
  1. 生成 Flutter LLDB 文件。

    1. 在你的 Flutter 应用中,运行以下命令
    flutter build ios --config-only

    这将在 .ios/Flutter/ephemeral 目录中生成 LLDB 文件。

  2. 设置 LLDB Init File。

    1. 前往Product > Scheme > Edit Scheme

    2. 在左侧边栏中选择Run部分。

    3. 使用与你在更新你的 Podfile部分中的 Podfile 中设置的 Flutter 应用相对路径相同的方式设置LLDB Init File

      $(SRCROOT)/../my_flutter/.ios/Flutter/ephemeral/flutter_lldbinit

      如果你的 Scheme 已有 LLDB Init File,你可以将 Flutter 的 LLDB 文件添加到其中。Flutter 的 LLDB Init File 的路径必须相对于你的项目的 LLDB Init File 的位置。

      例如,如果你的 LLDB 文件位于 /path/to/MyApp/.lldbinit,你将添加以下内容

      command source --relative-to-command-file "../my_flutter/.ios/Flutter/ephemeral/flutter_lldbinit"

在 Xcode 中链接和嵌入框架

#

方法

#

在第二种方法中,编辑你现有的 Xcode 项目,生成必要的框架,并将它们嵌入到你的应用中。Flutter 会为 Flutter 本身、你的编译 Dart 代码以及每个 Flutter 插件生成 iOS 框架。嵌入这些框架并更新你现有应用的构建设置。

要求

#

此方法不需要额外的软件或硬件要求。在以下使用场景中可以使用此方法

  • 你的团队成员无法安装 Flutter SDK 和 CocoaPods
  • 你不想在现有 iOS 应用中使用 CocoaPods 作为依赖项管理器

局限性

#

Flutter 无法处理 xcframeworks 的常见依赖项。如果宿主应用和 Flutter 模块的插件都定义了相同的 pod 依赖项,并且你使用此选项集成 Flutter 模块,则会导致错误。这些错误包括诸如 Multiple commands produce 'CommonDependency.framework' 之类的问题。

为了解决这个问题,请将 Flutter 模块中每个插件源代码的 podspec 文件链接到宿主应用的 Podfile。链接源代码而不是插件的 xcframework 框架。下一节将解释如何生成该框架

为了防止出现常见依赖项时发生的错误,请使用带有 --no-plugins 标志的 flutter build ios-framework 命令。

项目结构示例

#

以下示例假设你要将框架生成到 /path/to/MyApp/Flutter/

flutter build ios-framework --output=/path/to/MyApp/Flutter/

每次更改 Flutter 模块中的代码时都运行此命令。

生成的项目结构应类似于此目录树。

/path/to/MyApp/
└── Flutter/
    ├── Debug/
    │   ├── Flutter.xcframework
    │   ├── App.xcframework
    │   ├── FlutterPluginRegistrant.xcframework (only if you have plugins with iOS platform code)
    │   └── example_plugin.xcframework (each plugin is a separate framework)
    ├── Profile/
    │   ├── Flutter.xcframework
    │   ├── App.xcframework
    │   ├── FlutterPluginRegistrant.xcframework
    │   └── example_plugin.xcframework
    └── Release/
        ├── Flutter.xcframework
        ├── App.xcframework
        ├── FlutterPluginRegistrant.xcframework
        └── example_plugin.xcframework

步骤

#

在 Xcode 中如何将生成的框架链接、嵌入或同时进行这两种操作到你的现有应用中,取决于框架的类型。

Flutter 插件可能会生成静态或动态框架。链接静态框架,切勿嵌入它们

如果你将静态框架嵌入到你的 iOS 应用中,你将无法将该应用发布到 App Store。发布会因 Found an unexpected Mach-O header code 归档错误而失败。

#

要链接必要的框架,请遵循以下步骤。

  1. 选择要链接的框架。

    1. 项目导航器中,点击你的项目。

    2. 点击构建阶段选项卡。

    3. 展开Link Binary With Libraries

      Expand the Link Binary With Libraries build phase in Xcode
      在 Xcode 中展开Link Binary With Libraries构建阶段

    4. 点击+(加号)。

    5. 点击Add Other... 然后Add Files...

    6. 选择要添加的框架和库:对话框中,导航到 /path/to/MyApp/Flutter/Release/ 目录。

    7. 按住 Command 键点击该目录中的框架,然后点击打开

      Choose frameworks to link from the Choose frameworks and
libraries to add: dialog box in Xcode
      在 Xcode 的选择要添加的框架和库:对话框中选择要链接的框架

  2. 更新库的路径以适应构建模式。

    1. 启动 Finder。

    2. 导航到 /path/to/MyApp/ 目录。

    3. 右键点击 MyApp.xcodeproj 并选择显示包内容

    4. 用 Xcode 打开 project.pbxproj。该文件将在 Xcode 的文本编辑器中打开。这也会锁定项目导航器,直到你关闭文本编辑器。

      The  file open in the Xcode text editor
      在 Xcode 文本编辑器中打开的 project-pbxproj 文件

    5. /* Begin PBXFileReference section */ 中找到与以下文本相似的行。

      文本
      312885572C1A441C009F74FF /* Flutter.xcframework */ = {
        isa = PBXFileReference;
        expectedSignature = "AppleDeveloperProgram:S8QB4VV633:FLUTTER.IO LLC";
        lastKnownFileType = wrapper.xcframework;
        name = Flutter.xcframework;
        path = Flutter/Release/Flutter.xcframework;
        sourceTree = "<group>";
      };
      312885582C1A441C009F74FF /* App.xcframework */ = {
        isa = PBXFileReference;
        lastKnownFileType = wrapper.xcframework;
        name = App.xcframework;
        path = Flutter/Release/App.xcframework;
        sourceTree = "<group>";
      };
    6. 将上一步中高亮显示的 Release 文本更改为 $(CONFIGURATION)。同时用引号将路径括起来。

      文本
      312885572C1A441C009F74FF /* Flutter.xcframework */ = {
        isa = PBXFileReference;
        expectedSignature = "AppleDeveloperProgram:S8QB4VV633:FLUTTER.IO LLC";
        lastKnownFileType = wrapper.xcframework;
        name = Flutter.xcframework;
        path = "Flutter/$(CONFIGURATION)/Flutter.xcframework";
        sourceTree = "<group>";
      };
      312885582C1A441C009F74FF /* App.xcframework */ = {
        isa = PBXFileReference;
        lastKnownFileType = wrapper.xcframework;
        name = App.xcframework;
        path = "Flutter/$(CONFIGURATION)/App.xcframework";
        sourceTree = "<group>";
      };
  3. 更新搜索路径。

    1. 点击构建设置选项卡。

    2. 导航到搜索路径

    3. 双击框架搜索路径右侧。

    4. 在组合框中,点击+(加号)。

    5. 输入 $(inherited),然后按下 Enter

    6. 点击+(加号)。

    7. 输入 $(PROJECT_DIR)/Flutter/$(CONFIGURATION)/,然后按下 Enter

      Update Framework Search Paths in Xcode
      在 Xcode 中更新框架搜索路径

链接框架后,它们应该显示在目标的通用设置的框架、库和嵌入式内容部分中。

嵌入动态框架
#

要嵌入动态框架,请完成以下步骤。

  1. 导航到通用 > 框架、库和嵌入式内容

  2. 点击每个动态框架并选择嵌入并签名

    Select Embed  Sign for each of your frameworks in Xcode
    在 Xcode 中为每个框架选择嵌入并签名

    不要包含任何静态框架,包括 FlutterPluginRegistrant.xcframework

  3. 点击构建阶段选项卡。

  4. 展开嵌入框架。你的动态框架应该显示在该部分中。

    The expanded Embed Frameworks build phase in Xcode
    Xcode 中展开的嵌入框架构建阶段

  5. 构建项目。

    1. 在 Xcode 中打开 MyApp.xcworkspace

      验证你打开的是 MyApp.xcworkspace 而不是 MyApp.xcodeproj.xcworkspace 文件包含 CocoaPod 依赖项,而 .xcodeproj 不包含。

    2. 选择产品 > 构建 或按下 Cmd + B

设置 LLDB Init File

#
  1. 生成 Flutter LLDB 文件。

    1. 在你的 Flutter 应用程序中,如果尚未运行,请重新运行 flutter build ios-framework
    flutter build ios-framework --output=/path/to/MyApp/Flutter/

    这将在 /path/to/MyApp/Flutter/ 目录中生成 LLDB 文件。

  2. 设置 LLDB Init File。

    1. 前往Product > Scheme > Edit Scheme

    2. 在左侧边栏中选择Run部分。

    3. LLDB Init File设置为以下内容

      $(PROJECT_DIR)/Flutter/flutter_lldbinit

      如果你的 Scheme 已有 LLDB Init File,你可以将 Flutter 的 LLDB 文件添加到其中。Flutter 的 LLDB Init File 的路径必须相对于你的项目的 LLDB Init File 的位置。

      例如,如果你的 LLDB 文件位于 /path/to/MyApp/.lldbinit,你将添加以下内容

      command source --relative-to-command-file "Flutter/flutter_lldbinit"

在 Xcode 中使用框架并将 Flutter 框架作为 podspec

#

方法

#

此方法将 Flutter 生成为 CocoaPods podspec,而不是将大型 Flutter.xcframework 分发给其他开发人员、机器或持续集成系统。Flutter 仍然会为你的编译 Dart 代码以及每个 Flutter 插件生成 iOS 框架。嵌入这些框架并更新你现有应用程序的构建设置。

要求

#

此方法不需要额外的软件或硬件要求。在以下使用场景中可以使用此方法

  • 你的团队成员无法安装 Flutter SDK 和 CocoaPods
  • 你不想在现有 iOS 应用中使用 CocoaPods 作为依赖项管理器

局限性

#

Flutter 无法处理 xcframeworks 的常见依赖项。如果宿主应用和 Flutter 模块的插件都定义了相同的 pod 依赖项,并且你使用此选项集成 Flutter 模块,则会导致错误。这些错误包括诸如 Multiple commands produce 'CommonDependency.framework' 之类的问题。

为了解决这个问题,请将 Flutter 模块中每个插件源代码的 podspec 文件链接到宿主应用的 Podfile。链接源代码而不是插件的 xcframework 框架。下一节将解释如何生成该框架

为了防止出现常见依赖项时发生的错误,请使用带有 --no-plugins 标志的 flutter build ios-framework 命令。

此方法仅适用于 betastable 发布渠道

项目结构示例

#

以下示例假设你要将框架生成到 /path/to/MyApp/Flutter/

flutter build ios-framework --output=/path/to/MyApp/Flutter/

每次更改 Flutter 模块中的代码时都运行此命令。

生成的项目结构应类似于此目录树。

/path/to/MyApp/
└── Flutter/
    ├── Debug/
    │   ├── Flutter.xcframework
    │   ├── App.xcframework
    │   ├── FlutterPluginRegistrant.xcframework (only if you have plugins with iOS platform code)
    │   └── example_plugin.xcframework (each plugin is a separate framework)
    ├── Profile/
    │   ├── Flutter.xcframework
    │   ├── App.xcframework
    │   ├── FlutterPluginRegistrant.xcframework
    │   └── example_plugin.xcframework
    └── Release/
        ├── Flutter.xcframework
        ├── App.xcframework
        ├── FlutterPluginRegistrant.xcframework
        └── example_plugin.xcframework

将 Flutter 引擎添加到你的 Podfile

#

使用 CocoaPods 的宿主应用可以将 Flutter 引擎添加到它们的 Podfile 中。

MyApp/Podfile
ruby
pod 'Flutter', :podspec => '/path/to/MyApp/Flutter/[build mode]/Flutter.podspec'
#

Flutter 插件可能会生成静态或动态框架。链接静态框架,切勿嵌入它们

如果你将静态框架嵌入到你的 iOS 应用中,你将无法将该应用发布到 App Store。发布会因 Found an unexpected Mach-O header code 归档错误而失败。

#

要链接必要的框架,请遵循以下步骤。

  1. 选择要链接的框架。

    1. 项目导航器中,点击你的项目。

    2. 点击构建阶段选项卡。

    3. 展开Link Binary With Libraries

      Expand the Link Binary With Libraries build phase in Xcode
      在 Xcode 中展开Link Binary With Libraries构建阶段

    4. 点击+(加号)。

    5. 点击Add Other... 然后Add Files...

    6. 选择要添加的框架和库:对话框中,导航到 /path/to/MyApp/Flutter/Release/ 目录。

    7. 按住 Command 键点击该目录中的框架,然后点击打开

      Choose frameworks to link from the Choose frameworks and
libraries to add: dialog box in Xcode
      在 Xcode 的选择要添加的框架和库:对话框中选择要链接的框架

  2. 更新库的路径以适应构建模式。

    1. 启动 Finder。

    2. 导航到 /path/to/MyApp/ 目录。

    3. 右键点击 MyApp.xcodeproj 并选择显示包内容

    4. 用 Xcode 打开 project.pbxproj。该文件将在 Xcode 的文本编辑器中打开。这也会锁定项目导航器,直到你关闭文本编辑器。

      The  file open in the Xcode text editor
      在 Xcode 文本编辑器中打开的 project-pbxproj 文件

    5. /* Begin PBXFileReference section */ 中找到与以下文本相似的行。

      文本
      312885572C1A441C009F74FF /* Flutter.xcframework */ = {
        isa = PBXFileReference;
        expectedSignature = "AppleDeveloperProgram:S8QB4VV633:FLUTTER.IO LLC";
        lastKnownFileType = wrapper.xcframework;
        name = Flutter.xcframework;
        path = Flutter/Release/Flutter.xcframework;
        sourceTree = "<group>";
      };
      312885582C1A441C009F74FF /* App.xcframework */ = {
        isa = PBXFileReference;
        lastKnownFileType = wrapper.xcframework;
        name = App.xcframework;
        path = Flutter/Release/App.xcframework;
        sourceTree = "<group>";
      };
    6. 将上一步中高亮显示的 Release 文本更改为 $(CONFIGURATION)。同时用引号将路径括起来。

      文本
      312885572C1A441C009F74FF /* Flutter.xcframework */ = {
        isa = PBXFileReference;
        expectedSignature = "AppleDeveloperProgram:S8QB4VV633:FLUTTER.IO LLC";
        lastKnownFileType = wrapper.xcframework;
        name = Flutter.xcframework;
        path = "Flutter/$(CONFIGURATION)/Flutter.xcframework";
        sourceTree = "<group>";
      };
      312885582C1A441C009F74FF /* App.xcframework */ = {
        isa = PBXFileReference;
        lastKnownFileType = wrapper.xcframework;
        name = App.xcframework;
        path = "Flutter/$(CONFIGURATION)/App.xcframework";
        sourceTree = "<group>";
      };
  3. 更新搜索路径。

    1. 点击构建设置选项卡。

    2. 导航到搜索路径

    3. 双击框架搜索路径右侧。

    4. 在组合框中,点击+(加号)。

    5. 输入 $(inherited),然后按下 Enter

    6. 点击+(加号)。

    7. 输入 $(PROJECT_DIR)/Flutter/$(CONFIGURATION)/,然后按下 Enter

      Update Framework Search Paths in Xcode
      在 Xcode 中更新框架搜索路径

链接框架后,它们应该显示在目标的通用设置的框架、库和嵌入式内容部分中。

嵌入动态框架
#

要嵌入动态框架,请完成以下步骤。

  1. 导航到通用 > 框架、库和嵌入式内容

  2. 点击每个动态框架并选择嵌入并签名

    Select Embed  Sign for each of your frameworks in Xcode
    在 Xcode 中为每个框架选择嵌入并签名

    不要包含任何静态框架,包括 FlutterPluginRegistrant.xcframework

  3. 点击构建阶段选项卡。

  4. 展开嵌入框架。你的动态框架应该显示在该部分中。

    The expanded Embed Frameworks build phase in Xcode
    Xcode 中展开的嵌入框架构建阶段

  5. 构建项目。

    1. 在 Xcode 中打开 MyApp.xcworkspace

      验证你打开的是 MyApp.xcworkspace 而不是 MyApp.xcodeproj.xcworkspace 文件包含 CocoaPod 依赖项,而 .xcodeproj 不包含。

    2. 选择产品 > 构建 或按下 Cmd + B

设置 LLDB Init File

#
  1. 生成 Flutter LLDB 文件。

    1. 在你的 Flutter 应用程序中,如果尚未运行,请重新运行 flutter build ios-framework
    flutter build ios-framework --output=/path/to/MyApp/Flutter/

    这将在 /path/to/MyApp/Flutter/ 目录中生成 LLDB 文件。

  2. 设置 LLDB Init File。

    1. 前往Product > Scheme > Edit Scheme

    2. 在左侧边栏中选择Run部分。

    3. LLDB Init File设置为以下内容

      $(PROJECT_DIR)/Flutter/flutter_lldbinit

      如果你的 Scheme 已有 LLDB Init File,你可以将 Flutter 的 LLDB 文件添加到其中。Flutter 的 LLDB Init File 的路径必须相对于你的项目的 LLDB Init File 的位置。

      例如,如果你的 LLDB 文件位于 /path/to/MyApp/.lldbinit,你将添加以下内容

      command source --relative-to-command-file "Flutter/flutter_lldbinit"

设置本地网络隐私权限

#

在 iOS 14 及更高版本上,在你的 iOS 应用的调试版本中启用 Dart 多播 DNS 服务。这会通过 flutter attach 添加热重载和 DevTools 等调试功能

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

  1. 创建新的属性列表。

    1. 在 Xcode 中打开你的项目。

    2. 项目导航器中,点击项目名称。

    3. 在编辑器窗格的目标列表中,点击你的应用。

    4. 点击信息选项卡。

    5. 展开自定义 iOS 目标属性

    6. 右键点击列表并选择添加行

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

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

    1. 点击左侧项目列表中的信息文件。

    2. 在右侧的身份和类型面板中,将名称Info.plist 更改为 Info-Debug.plist

  3. 创建发布属性列表。

    1. 项目导航器中,点击 Info-Debug.plist

    2. 选择文件 > 复制...
      你也可以按下 Cmd + Shift + S

    3. 在对话框中,将另存为:字段设置为 Info-Release.plist 并点击保存

  4. 将必要的属性添加到调试属性列表。

    1. 项目导航器中,点击 Info-Debug.plist

    2. 将字符串值 _dartVmService._tcp 添加到Bonjour 服务数组。

    3. (可选)要设置你所需的自定义权限对话框文本,请添加键隐私 - 本地网络使用说明

      The  property list with the Bonjour Services
and Privacy - Local Network Usage Description keys added
      已添加Bonjour 服务隐私 - 本地网络使用说明键的 Info-Debug 属性列表

  5. 设置目标以对不同的构建模式使用不同的属性列表。

    1. 项目导航器中,点击你的项目。

    2. 点击构建设置选项卡。

    3. 点击全部合并子选项卡。

    4. 在搜索框中,输入 plist
      这会将设置限制为包含属性列表的设置。

    5. 滚动列表直到你看到打包

    6. 点击Info.plist 文件设置。

    7. Info.plist 文件的值从 path/to/Info.plist 更改为 path/to/Info-$(CONFIGURATION).plist更新构建设置以使用特定于构建模式的属性列表
      更新 Info.plist 构建设置以使用特定于构建模式的属性列表

      这会在调试模式下解析为路径Info-Debug.plist,在发布模式下解析为Info-Release.plist

      The updated Info.plist File build setting displaying the
configuration variations
      显示配置变体的已更新Info.plist 文件构建设置

  6. 构建阶段中移除发布属性列表。

    1. 项目导航器中,点击你的项目。

    2. 点击构建阶段选项卡。

    3. 展开复制捆绑资源

    4. 如果此列表中包含 Info-Release.plist,请点击它,然后点击其下方的-(减号)以从资源列表中移除该属性列表。

      The Copy Bundle build phase displaying the
Info-Release.plist setting. Remove this setting.
      显示Info-Release.plist设置的复制捆绑构建阶段。移除此设置。

  7. 你的调试应用加载的第一个 Flutter 屏幕会提示本地网络权限。

    点击确定

    (可选)要在应用加载前授予权限,请启用设置 > 隐私 > 本地网络 > 你的应用

解决 Apple Silicon Mac 上的已知问题

#

运行 Apple Silicon 的 Mac 上,宿主应用会为 arm64 模拟器构建。虽然 Flutter 支持 arm64 模拟器,但某些插件可能不支持。如果你使用了其中一个插件,你可能会看到类似Undefined symbols for architecture arm64的编译错误。如果发生这种情况,请在宿主应用中从模拟器架构中排除 arm64

  1. 项目导航器中,点击你的项目。

  2. 点击构建设置选项卡。

  3. 点击全部合并子选项卡。

  4. 架构下,点击排除的架构

  5. 展开以查看可用的构建配置。

  6. 点击调试

  7. 点击+(加号)。

  8. 选择iOS 模拟器

  9. 双击任何 iOS 模拟器 SDK 的值列。

  10. 点击+(加号)。

  11. 调试 > 任何 iOS 模拟器 SDK 对话框中输入 arm64

    Add  as an excluded architecture for your app
    arm64 添加为你的应用的排除架构

  12. 按下 Esc 关闭此对话框。

  13. 发布构建模式重复这些步骤。

  14. 对任何 iOS 单元测试目标重复此操作。

下一步

#

你现在可以将Flutter 屏幕添加到你现有的 iOS 应用中。