美文网首页iOS开发Flutter探索
iOS开发Flutter探索-与原生混合开发(11)

iOS开发Flutter探索-与原生混合开发(11)

作者: 泽泽伐木类 | 来源:发表于2020-06-23 16:15 被阅读0次

    前言

    混合开发(Hybird模式)是当下大部分APP开发的主流方式。通常我们将APP内变化比较频繁,业务比较轻,且对性能要求不是特别高的的功能,通过一些非原生的手段来实现,比如最简单的嵌套一个WebView,然后通过JSBridge的方式来实现双向通行,从而实现页面的动态更新;同样的在React Native,Weex,和Flutter中都提供的混合开发的能力。今天我们就看下Flutter如何与原生混合开发(这里主要以iOS开发为例);
    这里需要注意的是如果需要支持混合开发,整个Flutter项目需要创建为Module,然后将Module引入iOS/Android项目中,iOS通过cocoaPods来引入并加载。

    创建Flutter-Module项目

    截屏2020-06-22下午10.19.06.png
    项目结构对比
    两种类型项目对比.png
    我发现的唯一区别就是原来的androidios文件夹变成了隐藏文件。而且Module项目是可以独立运行的。

    创建一个iOS项目

    通常在Flutter混合开发项目中,我们的iOS或者Android项目会创建在Module的同级目录下(实际上就是为了引用个时候方便,其实我们完全可以将Module创建在任意位置,只是在项目中引用时路径太恶心罢了)。

    • 通过pod引入引入flutter_module,配置Podfile:
    # Uncomment the next line to define a global platform for your project
    flutter_application_path = '../flutter_module'
    load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
    
    platform :ios, '9.0'
    
    use_frameworks!
    target 'Flutter_iOS' do
      install_all_flutter_pods(flutter_application_path)
    end
    

    执行pod install,此时我们的原生项目就引入了整个flutter_module

    • 原生调起Flutter模块
    #import "ViewController.h"
    #import <Flutter/Flutter.h>
    @interface ViewController ()
    @property (nonatomic,strong) FlutterViewController *flutterVC;
    @end
    
    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.flutterVC = [[FlutterViewController alloc]init];
    }
    - (IBAction)toFlutterModule:(UIButton *)sender {  
        [self presentViewController:self.flutterVC animated:YES completion:nil];
    }
    @end
    

    这里值得注意的是flutterVC的初始化我没有放在点击事件内部,而是放在viewDidLoad中,FlutterViewController是一个特殊的视图控制器,并不像我们平常使用的UIViewController,在dismiss或者pop后会被释放,它不会被释放而且它被创建后的生命周期跟AppDelegate是一致的。
    在纯flutter项目中,FlutterViewController通常被指定为UIApplication.keyWindow.rootViewController

    调起效果图.gif

    通信

    这里主要用到的是MethodChannel

    Flutter官方图
    MethodChannel中两个核心的方法:
    1. setMethodCallHandler: 注册监听,处理收到的消息
    2. invokeMethod: 发送消息
    • Flutter
    class _HomePageState extends State<HomePage> {
      //创建通道,设置通道标识
      final MethodChannel _msgChannel = MethodChannel('msg_channel');
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        //添加监听,接受来自native的消息
        _msgChannel.setMethodCallHandler((MethodCall call){
          print('收到iOS的消息=>${call.method}\n${call.arguments}');
          return null;
        });
      }
    
    GestureDetector(
        onTap: (){
            print('onTap.....');
            //向native发送消息
            _msgChannel.invokeMethod('disMissVC',{'name':'zezefamily','age':'3','from':'Shannxi of China'});
        },
        child:  Text('返回上一页'),
    )
    
    • Native
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.flutterVC = [[FlutterViewController alloc]init];
        //创建通道,并绑定通道标识
        self.methodChannel = [FlutterMethodChannel methodChannelWithName:@"msg_channel" binaryMessenger:self.flutterVC];
        //添加监听:接收来自Flutter的消息
        __weak typeof(self) weakSelf = self;
        [self.methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
            
            if([call.method isEqualToString:@"disMissVC"]){
                [weakSelf dismissVC:call.arguments];
            }
            
        }];
    }
    - (void)dismissVC:(id)arguments
    {
        NSLog(@"来自Flutter=>%@",arguments);
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    - (IBAction)nativeToFlutter:(UIButton *)sender {
        //Native=>Flutter
        [self.methodChannel invokeMethod:@"msg_channel" arguments:@{@"name":@"我是原生",@"desc":@"我给你发消息了"}];
    }
    

    控制台输出:

    2020-06-23 15:20:54.568666+0800 Flutter_iOS[64555:1302095] flutter: onTap.....
    2020-06-23 15:20:54.569892+0800 Flutter_iOS[64555:1301842] 来自Flutter=>{
        age = 3;
        from = "Shannxi of China";
        name = zezefamily;
    }
    2020-06-23 15:20:56.594187+0800 Flutter_iOS[64555:1302095] flutter: 收到iOS的消息=>msg_channel
    {name: 我是原生, desc: 我给你发消息了}
    

    这样就实现了一个双向的通信能力,非常类似于WebViewJavascriptBridge

    j4i8b-w6dwn.gif

    总结

    参考文献:https://flutter.dev/docs/development/add-to-app

    相关文章

      网友评论

        本文标题:iOS开发Flutter探索-与原生混合开发(11)

        本文链接:https://www.haomeiwen.com/subject/lsoffktx.html