快速实现混合工程
1.创建一个文件夹
2.在新建的文件夹中使用XCode创建原生项目和flutter module,请参考iOS原生调起Flutter(OC)
3.启动原生工程,并生成调用flutter的代码
- (IBAction)toFlutterAction:(id)sender {
FlutterViewController *vc = [[FlutterViewController alloc] init];
[self presentViewController:vc animated:YES completion:nil];
}
点击按钮触发上面的方法,跳转到flutter,效果如下:
注:此处只是为了快速调起flutter,更优的方式请参考iOS原生调起Flutter(OC)
这样我们就快速的实现了原生调用flutter的混合工程,这对于flutter工程师来说似乎不存在多大的问题了。
但是我们知道,原生的工程师并不懂flutter,也不会构建flutter环境。就算原生工程师都会flutter,并会构建flutter环境,但每个原生的工程师都要构建一次flutter环境,是不是也很浪费时间。而且,flutter工程师和原生工程师创建的flutter工程师的路径还得一样。下面我把本地的flutter移除,再运行一下刚刚的工程。
通过上图,把flutter移除到了废纸篓,本地的flutter就没有了。这时候我们打开原生工程,运行起来,报错了!!!
报错的原因是"/Users/iot_user/flutter/packages/flutter_tools/bin/xcode_backend.sh"路径下的xcode_backend.sh脚本文件去执行flutterSDK里面的文件时,找不到文件了。这样就要求flutter原生的工程必须要有flutter的环境,并且flutter的路径和版本号都要保持一致,但对于混合开发的原生工程师来说是非常不合理的。那么我们如何解决这个问题呢?
混合工程自动化方法一
将flutter_module打包成framework,不过这个功能是在flutter 1.12以后才有的。
1.打开终端,cd到flutter_module所在的文件中,执行以下命令
flutter build ios-framework --output=../flutter_app
执行效果如下:
其中“../flutter_app”是生成的framework文件存放的路径,这里将其放在上级目录
执行后得到如下图三个文件
- Debug--使用在模拟器上的调试版本;
- Release--发布版本;
- Profile--高性能调试版本,只能使用在真机上。
分别打开以上三个文件,我们发现三个文件中都有一个App.framework和Flutter.framework文件。App.framework文件就是Flutter开发人员写的dart代码编译之后的产物;Flutter.framework文件就是Flutter引擎的代码。运行的时候,Flutter引擎会去解析App.framework的代码。
下面我们以Debug版本为例来使用一下framework文件 1.将flutter_app拖进原生工程所在的目录
2.配置framework文件的工程路径
3.将framework文件添加到工程中
4.使用framework实现原生调起flutter
//
// ViewController.m
// FlutterDemo2
//
// Created by iot_user on 2020/7/14.
// Copyright © 2020 IOT. All rights reserved.
//
#import "ViewController.h"
#import <Flutter/Flutter.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (IBAction)pushFlutter:(id)sender {
FlutterViewController *vc = [[FlutterViewController alloc] init];
[self presentViewController:vc animated:YES completion:nil];
}
@end
这样我们就成功实现了在混合工程的自动化,当我们把电脑中没有flutter的环境时,也能正常的运行,实现了真正的混合开发。
这样实现,同样存在一些不如人意的地方,每次更新后,都要将两个文件生成后发送给原生工程师进行替换。而且,更多时候,只有App.framework是经常更新的,Flutter.framework文件基本是不会改变的。那么我们是否有更优的方案来优化一下呢?
混合工程自动化方法二
使用cocoapods的方式引入framework
1.以cocoapods的方式生成framework文件
终端cd到flutter module文件所在的目录,输入如下指令生成cocoapods下的framework文件
flutter build ios-framework --cocoapods --output=../Flutter
通过执行上面的命令,同样得到三个文件
我们打开其中一个
我们发现,和上面生成framework的方式不同的是,Flutter.framework变成了Flutter.podspec。Flutter.podspec就是cocoapods的脚本,使用它就可以接入Flutter的工程。
2.创建原生工程,并配置cocoapods
3.在podfile文件中加入如下代码,并pod install
pod 'Flutter', :podspec => 'Flutter/Debug/Flutter.podspec'
'Flutter/Debug/Flutter.podspec'就是项目当前依赖的flutter代码的文件路径
这样我们就把framework引入了原生工程中
这时候原生的项目工程中就有了flutter引擎了
4.导入App.framework文件,并配置
5.使用framework
//
// ViewController.m
// FlutterDemo
//
// Created by iot_user on 2020/7/14.
// Copyright © 2020 IOT. All rights reserved.
//
#import "ViewController.h"
#import <Flutter/Flutter.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (IBAction)pushFlutter:(id)sender {
FlutterViewController *Vc = [[FlutterViewController alloc] init];
[self presentViewController:Vc animated:YES completion:nil];
}
@end
这样我们就成功调起了flutter,并且不需要flutter环境的支持。