美文网首页
flutter与原生混编(iOS)

flutter与原生混编(iOS)

作者: 夏天爱西瓜汁 | 来源:发表于2021-03-12 15:16 被阅读0次

    一、创建项目及配置
    1,创建ios项目,同时在同一个根目录下创建flutter项目
    flutter项目使用命令flutter create -t module xxxflutter项目名
    如图


    工程目录.png

    2,将flutter项目以pod的形式加入ios项目
    2.1,如果项目之前没有用过pod,则pod init创建podfile
    如果使用过,直接进行步骤2.2。
    2.2,podfile中添加

    flutter_application_path = '../xxxflutter项目名'
    load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
    

    flutter_application_path是flutter项目的路径
    2.3,target中加入(一次性将flutter的编译产物由此依赖进入iOS项目中,可跳过步骤3)

    install_all_flutter_pods(flutter_application_path)
    

    3,配置脚本(已完成步骤2.3可进行步骤4)
    打开ios项目,在Build Phases中左上角添加Run Script


    添加Run Script.png
    Run Script内容.png
    "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
    "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed 
    

    4,设置bitcode
    Flutter 目前还不支持 BitCode,需要设置为No


    图片.png

    二、混编使以后添加的每个模块都以package形式,在module中pubspec.yaml文件中引用(基于内存消耗考虑)
    1,页面跳转
    原生处理:
    flutter在iOS中的使用,主要是以FlutterViewController为载体,并在其内部采用FlutterEngine对视图进行渲染。
    导入头文件:

    #import <Flutter/Flutter.h>
    初始化FlutterEngine:
    FlutterEngine *engine = [[FlutterEngine alloc] initWithName:@"xxx"];//xxx是唯一标识
    if ([engine run]) {
        self.flutterEngine = engine;
    }
    
    初始化flutter控制器
    _flutterVC = [[FlutterViewController alloc] initWithEngine:self.flutterEngine nibName:nil bundle:nil];
    
    跳转
    //“channelA”与flutter定义的名字保持一致
    FlutterMethodChannel *methodChannel = [FlutterMethodChannel methodChannelWithName:@"channelA" binaryMessenger:self.flutterVC];
    //使用指定的参数调用指定的Flutter方法,“methodA”与flutter定义的名字保持一致
    [methodChannel invokeMethod:@"methodA" arguments:nil];
    
    根据flutter定义的方法名做相应的操作:在flutter页面点击按钮跳转至原生页面
    [methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
        if ([call.method isEqualToString:@"next"]) { //”next“为flutter定义的方法
            NativeViewController *vc = [[NativeViewController alloc] init];
            [self.navigationController pushViewController:vc animated:YES];
        }
    }];
    [self.navigationController pushViewController:self.flutterVC animated:YES]; //跳转至flutter页面
    

    flutter处理:
    在module项目的main里

    导入头文件
    import 'package:flutter/services.dart';
    

    定义channel,名字与原生保持一致

    final MethodChannel _channelA = MethodChannel("methodA");
    在init方法里添加在该channel上接收方法的回调
    此处_pageIndex用来处理显示flutter哪个页面
    _channelOne.setMethodCallHandler((call) {
      setState(() {
        _pageIndex = call.method;
      });
      return null;
    });
    
    flutter页面点击按钮跳转至原生页面
    onTap: () {
      MethodChannel(“channelA”).invokeMethod(“next”); 
      //channel名字和method名字需与原生保持一致
    }
    

    2,数据传递
    二者之间的数据传递iOS使用FlutterBasicMessageChannel类,flutter使用BasicMessageChannel类,用法与MethodChannel类似
    原生处理:

    初始化channel
    self.msgChannel = [FlutterBasicMessageChannel messageChannelWithName:@“messageChannel" binaryMessenger:self.flutterVC];//同样 channel名字与flutter保持一致
    

    接收数据:

    处理接收到的flutter数据
    [self.msgChannel setMessageHandler:^(id  _Nullable message, FlutterReply  _Nonnull callback) {
        NSLog(@"收到了来自flutter的消息:%@",message);
    }];
    

    发送数据:

    在需要向flutter发送数据的地方调用
    [self.msgChannel sendMessage:message];
    

    flutter处理:

    首先依然是导入头文件
    import 'package:flutter/services.dart';
    
    初始化channel,channel名字与原生保持一致
    final BasicMessageChannel _msgChannel =
     BasicMessageChannel("messageChannel", StandardMessageCodec());
    
    接收数据:
    在init方法里添加在该channel上接收方法的回调
    _msgChannel.setMessageHandler((message) {
      print("收到了来之iOS的消息:$message");
      return null;
    });
    
    发送数据:在需要的地方之间调用send方法即可
    _msgChannel.send(message);
    

    问题:


    问题.png

    网上搜的方法,在podfile最前边加eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)句话
    执行pod install失败

    # Uncomment the next line to define a global platform for your project
    # platform :ios, '9.0'
    
    flutter_application_path = '../flutter_module'
    eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
    
    target 'iosfix' do
      # Comment the next line if you don't want to use dynamic frameworks
      use_frameworks!
    
      # Pods for iosfix
      install_all_flutter_pods(flutter_application_path)
    
      target 'iosfixTests' do
        inherit! :search_paths
        # Pods for testing
        install_all_flutter_pods(flutter_application_path)
      end
    
      target 'iosfixUITests' do
        # Pods for testing
        install_all_flutter_pods(flutter_application_path)
      end
    
    end
    
    

    于是又搜了下别的文章,添加的第二句话为load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb'),试了下成功了

    相关文章

      网友评论

          本文标题:flutter与原生混编(iOS)

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