# 第1节：iOS项目集成Flutter

本节学习内容：在已有的iOS项目中集成Flutter，以使得您的iOS项目中的部分界面/功能可以通过Flutter来实现。

本节学习用时：**30分钟**

本节学习方式：动手实践

本节目录：

一、集成方式介绍

二、集成方法一：手动配置iOS与Flutter的混编环境

三、集成方法二：Pod集成Flutter方式

四、集成后调用Flutter界面的代码编写

### 一、集成方式介绍

本节将介绍两种在已有的iOS项目中集成Flutter的方法，分别为①手动配置iOS与Flutter的混编环境、②Pod集成Flutter方式。

下面表格是两种集成Flutter的方法比较：

|                      | 手动集成Flutter         | Pod集成Flutter                                  |
| -------------------- | ------------------- | --------------------------------------------- |
| 集成速度                 | 需要自己建立文件、进行相应配置，并替换 | 执行Pod及Run Script即可                            |
| Flutter项目更新时         | 每次都需要替换             | 不用替换                                          |
| Flutter项目与iOS同时路径变更时 | 不影响iOS工程            | <p>Flutter工程需要重新编译执行；<br>然后iOS工程需再重新执行Pod</p> |

### 二、集成方法一：手动配置iOS与Flutter的混编环境

#### 1.1 集成后的最后项目结构如图：

> ![myiosproject project structure](/files/-LVmK98jUxoUpPS9Hj2M)

#### 1.2 集成后的最后文件结构如图：

> ![myiosproject file structure](/files/-LVmK98lQ15N827TYDPd)

#### 1.3 详细的集成实现步骤如下：

* ①、通过终端命令在指定目录(这里我们选择iOS项目的同级目录)创建myfluttermodule。`flutter create -t module myfluttermodule`
* ②、Xcode：创建iOS项目，设为myiosproject；
* ③、Xcode：创建配置衔接文件
  * 在②中建立的iOS项目中新建`Config`目录，用于存放/管理接下来Xcode工程需要创建的的配置衔接文件；
  * 选择创建`Configuration Settings File`文件，分别创建名为 `Flutter.xcconfig`、`Debug.xcconfig`、`Release.xcconfig`的三个配置文件；

    > ![New Configuration Settings File](/files/-LVmK98nihawMDA1mCjL)
  * 完善`Flutter.xcconfig`、`Debug.xcconfig`、`Release.xcconfig`三个配置文件的内容为分别如下：

    > Flutter.xcconfig 配置文件内容如下：
    >
    > ```
    > //Flutter.xconfig,用于指向外目录flutter module的`Generated.xcconfig`文件路径引用文件
    >
    > //这里填写前面建立的 myfluttermodule 的Generated.xcconfig的路径
    > #include "../../myfluttermodule/.ios/Flutter/Generated.xcconfig"
    > ENABLE_BITCODE=NO
    > ```
    >
    > Debug.xcconfig 配置文件内容如下：
    >
    > ```
    > //Debug.xconfig，Xcode的环境配置文件
    >
    > #include "Flutter.xcconfig"
    > //#include "../Pods/Target Support Files/******.debug.xcconfig"//pod路径
    > #include "../Pods/Target Support Files/Pods-myiosproject/Pods-myiosproject.debug.xcconfig"//pod路径
    > FLUTTER_BUILD_MODE=debug
    > ```
    >
    > Release.xcconfig 配置文件内容如下：
    >
    > ```
    > //Release.xconfig，Xcode的环境配置文件
    >
    > #include "Flutter.xcconfig"
    > //#include "../Pods/Target Support Files/******.release.xcconfig"//pod路径
    > #include "../Pods/Target Support Files/Pods-myiosproject/Pods-myiosproject.release.xcconfig"//pod路径
    > FLUTTER_BUILD_MODE=release
    > ```
  * 修改Xcode Project的环境配置选择

    > ![myiosproject Project Info Configurations](/files/-LVmK98pk4R9I0YCrn7K)
* ④、Xcode -> Target -> Build Phases -> New Run Script Phase，添加要执行的脚本内容引入`xcode-backend.sh`，此步很重要。

  ```
  "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
  "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed
  ```

  > ![myiosproject New Script xcode-backend.sh](/files/-LVmK98ru43_BJEJt1Wz)
* ⑤、添加/替换flutter编译产物，**如果之前已添加，则这里每次有有新的时候，注意要替换掉，否则界面还是旧的。**

  > 即复制 myfluttermodule/.ios/Flutter下的`App.framework`、`engine`、`flutter_assets`进行替换。
  >
  > 然后Xcode重新编译即可。
  >
  > 注意：`flutter_assets` 并不能使用`Create groups` 的方式添加，只能使用`Creat folder references` 的方式添加进Xcode项目内，否则跳转flutter会页面渲染失败（页面空白）。
* ⑥、至此，恭喜你，到这里您可向往常一样直接执行已集成Flutter的Xcode项目了。

### 三、集成方法二：Pod集成Flutter方式

#### 2.1 最后的项目结构如图：

> ![myiosproject2 project structure](/files/-LVmK98tLOoqd1HdcM9w)

#### 2.2 实现步骤如下：

* ①、通过终端命令在指定目录(这里我们选择iOS项目的同级目录)创建myfluttermodule。`flutter create -t module myfluttermodule`。这里因为我们已经在1中实现，所以不再重复创建。
* ②、Xcode：创建myiosproject2；添加如Podfile，及在Podfile中如结构图中所示，补充

  ```
      flutter_application_path = './../myfluttermodule/'
      eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
  ```

  后，执行pod install

  > ![myiosproject2 pod install](/files/-LVmK98vufh52A7AfoC3)
* ③、Xcode -> Target -> Build Phases -> New Run Script Phase，添加要执行的脚本内容引入`xcode-backend.sh`，此步很重要。同1中一样的做法。
* ④、至此，混编环境配置成功！

### 四、集成后调用Flutter界面的代码编写

```
#import "AppDelegate.h"
#import <Flutter/Flutter.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
//    ViewController *viewController = [[ViewController alloc] init];
//    UIViewController *rootViewController = [[UINavigationController alloc] initWithRootViewController:viewController];
    UIViewController *rootViewController = [[FlutterViewController alloc] initWithProject:nil nibName:nil bundle:nil];
    self.window.rootViewController = rootViewController;
    [self.window makeKeyAndVisible];

    return YES;
}
```

而后，正常执行Xcode项目即可。

## 三、更多混编

更多混编知识，请查看[官网：使用平台通道编写平台特定的代码](https://flutterchina.club/platform-channels/)

> ![platform channel](/files/-LVmK98xJ68VljDY4Hmy)

## 附：


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://devbook.site/2-ji-cheng/ios-xiang-mu-ji-cheng-flutter.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
