官方解决方案:https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps
这一篇讲一下iOS老项目集成Flutter流程。并且实现
ProtocolTest
集成了Cocoapods
Enable Bitcode
需要关闭,因为Flutter混合开发不支持BitcodeProtocolTest
的父级文件夹Flutter_OC
创建flutter_modulecd ProtocolTest`的父级文件夹`Flutter_OC
flutter create -t module flutter_module
执行完flutter create -t module flutter_module
命令后目录如下
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed
注意: Run Script 在Target Dependencies或者[CP]Check pods Manifest.lock后面
Podfile
修改一下,以便将flutter包括在里面platform :ios, '9.0'
target 'myproject' do
end
#新添加的代码
flutter_application_path = '../'
eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
我的Podfile
如下
# Uncomment this line to define a global platform for your project
use_frameworks!
source 'https://github.com/CocoaPods/Specs.git' # 公开的第三方库
source 'https://gitee.com/muyushifang07/MYCode_tools_repos.git' # 私有库
platform :ios, '9.0'
target 'ProtocolTest' do
#不带:path 的pod install 成功后会生成Pods 文件夹,里面都是远端github的库
pod 'AFNetworking'
#pod 'RSAHandlerDemo' ,:path => 'https://github.com/muyushifang07/RSAHandlerDemo.git'
pod 'MYHexTool','~>0.1.0'
## ==============Flutter ==============_
## Flutter 模块的路径 pod update --verbose --no-repo-update_
##绝对路径_
flutter_application_path = '/Users/suning/Desktop/flutterdemos/Flutter_OC/flutter_module'
eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
## ==============Flutter ==============_
end
终端执行 pod install
执行后pod install
Pod 文件目录如下:flutter被包涵进来了
在OC中调用Flutter Module有两种方式
1)直接使用FlutterViewController的方式;
2) 使用FlutterEngine的方式;
我这里实现了第一种方式:跳转路径
pushToFlutterPage
点击跳到Flutter 的main.dart
页面。main.dart
页面放置按钮Push 到 FLutter的FirstScreen.dart
页面FirstScreen.dart
页面放置按钮Push 到 OC的SettingViewController
页面ViewController.m
#import "ViewController.h"
#import
#include "GeneratedPluginRegistrant.h"
#import "SettingViewController.h"
@interface ViewController ()
{
FlutterViewController *flutterVC;
FlutterMethodChannel *batteryChannel;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.title = @"我是iOS 页面";
flutterVC = [[FlutterViewController alloc]initWithProject:nil nibName:nil bundle:nil];
flutterVC.title = @"我是Flutter页面";
batteryChannel = [FlutterMethodChannel methodChannelWithName:@"samples.flutter.dev/battery" binaryMessenger:flutterVC];
}
- (IBAction)pushNext:(id)sender {
NSLog(@"你好吗?");
//如果使用了插件显示view
[GeneratedPluginRegistrant registerWithRegistry:flutterVC];
//[flutterVC setInitialRoute:@"myApp12"];
[flutterVC setInitialRoute:@"myApp"];
[self.navigationController pushViewController:flutterVC animated:YES];
__weak typeof(self) weakSelf = self;
[batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
// Note: this method is invoked on the UI thread.
if ([@"getBatteryLevel" isEqualToString:call.method])
{
int batteryLevel = [weakSelf getBatteryLevel];
if (batteryLevel == -1) {
result([FlutterError errorWithCode:@"UNAVAILABLE" message:@"Battery info unavailable" details:nil]);
} else {
result(@(batteryLevel));
}
} else if ([@"backToNavigatorIndex" isEqualToString:call.method]) {
NSArray *arguments = call.arguments;
NSNumber *inde = arguments[0];
NSLog(@"arguments :%@",inde);
int batteryLevel = [weakSelf backToNavigatorIndex:inde];
result(@(batteryLevel));
} else {
result(FlutterMethodNotImplemented);
}
}];
}
- (IBAction)passArgusToFlutter:(id)sender {
NSLog(@"passArgusToFlutter");
[batteryChannel invokeMethod:@"passArgusToFlutter" arguments:@[@12,@"huahua"] result:^(id _Nullable result) {
NSString *ggg = (NSString *)result;
NSLog(@"result----:%@",ggg);
}];
}
- (int)getBatteryLevel {
NSLog(@"nihao!!!!!");
SettingViewController *settingVC = [[SettingViewController alloc]init];
[flutterVC.navigationController pushViewController:settingVC animated:YES];
return 66;
}
- (int)backToNavigatorIndex:(NSNumber*)index {
NSLog(@"backToNavigatorIndex!!!!!");
UIViewController *VC = flutterVC.navigationController.viewControllers[0];
[flutterVC.navigationController popToViewController:VC animated:YES];
return 33;
}
SettingViewController 没有任何其他代码就是新建一个控制器
新建一个页面FirstScreen.dart
main.dart
改动代码
import 'dart:ui' as ui;
import 'package:flutter_module/FirstScreen.dart';
//void main() => runApp(MyApp());
void main() => runApp(_widgetForRoute(ui.window.defaultRouteName));
Widget _widgetForRoute(String route) {
switch (route) {
case 'myApp':
return MyApp();
default:
return MaterialApp(
home: Center(
child: Text('没找到'),
),
);
}
}
增加一个函数跳转:FirstScreen.dart
class _MyHomePageState extends State {
......
Future _goOCPage(BuildContext context) async {
print('我要去Flutter 的下一个页面了');
Navigator.push(context, MaterialPageRoute(builder: (context){
return new FirstScreen();
}));
}
......
}
在body的{} 中添加一个文本和按钮FlatButton
用于跳转到FirstScreen.dart
Text(
'自我介绍,我是flutter页面',
),
FlatButton(
child: Text("去下一个Flutter页面"),
textColor: Colors.blue,
onPressed: (){
_goOCPage(context);
},
),
FirstScreen.dart
的全部代码
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
class FirstScreen extends StatelessWidget {
static const platform = const MethodChannel('samples.flutter.dev/battery');
Future _goOCPage() async {
print('我要去OC 页面了');
String batteryLevel;
try {
final int result = await platform.invokeMethod('getBatteryLevel');
batteryLevel = 'Battery level at $result % .';
} on PlatformException catch (e) {
batteryLevel = "Failed to get battery level: '${e.message}'.";
}
print('调用了$batteryLevel');
}
Future _goSomePage() async {
print('我要去导航的指定页面了');
String batteryLevel;
try {
final int result = await platform.invokeMethod('backToNavigatorIndex',[1]);
batteryLevel = 'backSmoePahe $result % .';
} on PlatformException catch (e) {
batteryLevel = "Failed to backSmoePahe: '${e.message}'.";
}
print('back$batteryLevel');
}
@override
Widget build(BuildContext context) {
Future _handler(MethodCall methodCall) {
if ("passArgusToFlutter" == methodCall.method) {
print('methodCall-arguments:${methodCall.arguments}');
}
return Future.value(123);
}
platform..setMethodCallHandler(_handler);
return Scaffold(
appBar: AppBar(
title: Text('FirstScreen 页面'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'自我介绍,我是flutter页面',
),
FlatButton(
child: Text("backLastPage"),
textColor: Colors.blue,
onPressed: (){
Navigator.pop(context);
},
),
FlatButton(
child: Text("goOCPage"),
textColor: Colors.blue,
onPressed: (){
_goOCPage();
},
),
FlatButton(
child: Text("backToSomePage"),
textColor: Colors.blue,
onPressed: (){
_goSomePage();
},
),
],
),
),
);
}
}
Xcode 运行项目即可。
Flutter基础系列之混合开发(二)
A : 首先在命令行启动flutter的监听
flutter attach
如果有多台设备,需要选择一下设备
flutter attach -d 设备标志
flutter和原生项目混合开发
Flutter基础系列之混合开发(二)