混合开发

在一个原有的原生项目中嵌入Flutter页面,而Flutter也提供了相应的支持。

创建module

image.png

也可以使用命令行 flutter create -t module flutter_module

FLutter项目嵌入

首先创建Flutter Module,命名为flutter_module,将module项目和原生项目放到同级目录,然后在Podfile文件中:

  1. # Uncomment the next line to define a global platform for your project
  2. # platform :ios, '9.0'
  3. flutter_application_path = '../flutter_module'
  4. load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
  5. target 'NativeDemo' do
  6. install_all_flutter_pods(flutter_application_path)
  7. use_frameworks!
  8. # Pods for NativeDemo
  9. end

执行pod install命令
通过cocoapods,Flutter 模块就嵌入原生项目工程了。

Flutter页面调用

通过导入,就可以调用Flutter页面了。

  1. #import <Flutter/Flutter.h>
  2. FlutterViewController *vc = [[FlutterViewController alloc] init];
  3. vc.modalPresentationStyle = UIModalPresentationFullScreen;//全屏
  4. [self presentViewController:vc animated:YES completion:nil];

可以看到调起的页面是main.dart中的页面,如果要调起指定的flutter页面,可以通过

  1. FlutterViewController *vc = [[FlutterViewController alloc] init];
  2. vc.modalPresentationStyle = UIModalPresentationFullScreen;//全屏
  3. [vc setInitialRoute:@"one"];
  4. [self presentViewController:vc animated:YES completion:nil];


传递指定标示路由,然后在main.dart中通过window.defaultRouteName拿到InitialRoute现实对应的Flutter页面(通过StatefulWidget变化页面)

  1. import 'dart:ui';
  2. void main() => runApp(MyApp(
  3. pageIndex: window.defaultRouteName,
  4. ));
  5. class MyApp extends StatelessWidget {
  6. final String pageIndex;
  7. const MyApp({Key key, this.pageIndex}) : super(key: key);
  8. // This widget is the root of your application.
  9. @override
  10. Widget build(BuildContext context) {
  11. return MaterialApp(
  12. title: 'Flutter Demo',
  13. theme: ThemeData(
  14. highlightColor: Color.fromRGBO(1, 0, 0, 0.0), //点击高亮设置为透明
  15. splashColor: Color.fromRGBO(1, 0, 0, 0.0), //水波纹色设置为透明
  16. primarySwatch: Colors.blue,
  17. ),
  18. home: _rootPage(pageIndex),
  19. );
  20. }
  21. _rootPage(String pageIndex) {
  22. switch (pageIndex) {
  23. case 'one':
  24. return Scaffold(
  25. appBar: AppBar(
  26. title: Text(pageIndex),
  27. ),
  28. body: Center(
  29. child: Text(pageIndex),
  30. ),
  31. );
  32. case 'two':
  33. return Scaffold(
  34. appBar: AppBar(
  35. title: Text(pageIndex),
  36. ),
  37. body: Center(
  38. child: Text(pageIndex),
  39. ),
  40. );
  41. }
  42. }
  43. }


混合工程开发需要解决的问题

原生开发者,需要配置Flutter环境 (ios工程需要执行脚本:Flutter目录/packages/flutter_tools/bin/xcode_backend.sh) + Flutter的版本和路径必须和Flutter开发者保持一致

解决方案1

1. 需要将flutter_module工程打包成一个Framework

进入flutter_module目录,执行脚本

  1. flutter build ios-framework --output=../flutter_app

将flutter_module工程打包成Framework 是Flutter 1.12之后才有的功能

image.png

只有Debug版本运行在模拟器 Profile和Release都只支持真机

2 NativeDemo配置

将flutter_app目录拷贝到NativeDemo工程目录下
Debug配置:

  • 配置Framework Search Paths

配置Debug的Search Paths:
$(inheritied)
$(PROJECT_DIR)/flutter_app/Debug

image.png

  • 在工程中添加目录Frameworks文件夹,并在配置中拖入flutter_app/Debug目录中的两个framework

image.png

3. NativeDemo就可以直接使用App.framework 和 Flutter.framework

解决方案2

1.工程打包成一个cocoapods的App.framework和Flutter.podspec

进入flutter_module目录,执行脚本

  1. flutter build ios-framework --cocoapods --output=../Flutter

image.png

2.原生NativeDemo的配置

将Flutter目录拷贝到NativeDemo工程目录下

  • Podfile配置—> pod install

image.png

  • 配置Debug的Search Paths:

$(inheritied)
$(PROJECT_DIR)/Flutter/Debug

  • 在工程中添加目录Frameworks文件夹,并在配置中拖入Flutter/Debug目录中的App.framework

image.png

自动化

在github创建仓库

image.png
10.12及以上系统需要配置 :vi ~/.ssh/config
image.png


原生NativeDemo

将Flutter目录拷贝到NativeDemo工程目录下

  • Podfile配置—> pod install

image.png

  • 配置Debug的Search Paths:

$(inheritied)
$(PROJECT_DIR)/Flutter/Debug

  • 在工程中添加目录Frameworks文件夹,并在配置中拖入Flutter/Debug目录中的App.framework

flutter_module编码和NativeDemo编码,提交到git

CI配置

  • 添加Action

image.png

  • 添加的Action脚本 ```bash name: FlutterCI #CI名称 on: [push] #触发条件push操作!

jobs: check: name: Test on ${{ matrix.os }}

  1. #运行在哪个平台这里是MacOS平台
  2. runs-on: macos-latest
  3. steps:
  4. - uses: actions/checkout@v1#固定写法
  5. #三方flutter的Action,它可以在服务器配置一个Flutter环境
  6. - uses: subosito/flutter-action@v1
  7. with:
  8. flutter-version: '1.17.1'
  9. channel: 'stable'
  10. #想让我们CI做的事情!
  11. - run: cd flutter_module && flutter build ios-framework --cocoapods --output=../NativeDemo/Flutter
  12. - run: |
  13. git add .
  14. git commit -m 'update flutter framework'
  15. - name: Push changes
  16. uses: ad-m/github-push-action@master
  17. with:
  18. github_token: ${{ secrets.GITHUB_TOKEN }}

```

  • 提交CI脚本

image.png

  • CI 编译完成:

image.png