美文网首页Flutter学习笔记flutter
2020最新flutter模块集成到原生iOS项目(一)

2020最新flutter模块集成到原生iOS项目(一)

作者: WinJayQ | 来源:发表于2020-01-31 21:17 被阅读0次

    一、项目背景

     * 公司的App主要面向政企事业单位,用来协同办公,其中有个动态模块(类似朋友圈与博客)
     * 领导安排了一位同事将原生的动态用flutter重新写了一遍,主要是UI方面
     * 大部分业务使用Channel机制与原生通信,并使用路由跳转不同的原生页面
    

    二、参考add-to-app文档

    三、集成的详细步骤

    1、将Flutter SDK集成到原生项目中

    1)为了将 Flutter 集成到你的既有应用里,第一步要创建一个 Flutter module

    cd /Users/xxx/Documents/ProjectName   (cd到项目的文件夹)
    flutter create --template module flutter_module
    
    • 我为了图方便,将flutter_module(名称自定义)目录放在了ProjectName里面,add-to-app文档推荐flutter_module与ProjectName同级
    • 如下图表示创建成功:


      image.png

    2)使用 CocoaPods 依赖管理和已安装的 Flutter SDK 。(推荐)

    在ProjectName的Podfile中添加代码

    flutter_application_path = './flutter_module'
    load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
    
    • 注意:flutter_module名称是自定义,并且路径也是自己的真实路径 './flutter_module'是因为我的flutter_module在ProjectName里面,如果同级,则路径是'../flutter_module'
    • 通过修改flutter_application_path也可以切换不同的flutter_module,方便测试,比如你还有个flutter_test,只需要修改flutter_application_path = './flutter_test',注意路径要跟你自己的一致,然后pod install就可以了

    在target中添加代码

    target 'ProjectName' do
       install_all_flutter_pods(flutter_application_path)
     end
    

    • podhelper.rb 脚本会把你的 plugins, Flutter.framework,和 App.framework 集成到你的项目中。
    pod install成功如下图:


    image.png
    • flutter中的依赖如果有修改的话,都需要重新执行pod install

    3)工程目录中能看到如下图:

    image.png
    • 此时在Xode中编译成功

    2、在 iOS 应用中添加 Flutter 页面

    1)创建一个 FlutterEngine
    在 AppDelegate.h:

    #import <Flutter/Flutter.h>
    @interface AppDelegate : FlutterAppDelegate
    @property (nonatomic,strong) FlutterEngine *flutterEngine;
    

    在 AppDelegate.m:

    #import <FlutterPluginRegistrant/GeneratedPluginRegistrant.h>
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.flutterEngine = [[FlutterEngine alloc] initWithName:@"my flutter engine"];
        [self.flutterEngine run];
        [GeneratedPluginRegistrant registerWithRegistry:self.flutterEngine];
    
        return [super application:application didFinishLaunchingWithOptions:launchOptions];
    }
    

    2)在你想要集成flutter的ViewController中
    添加:

    #import "AppDelegate.h"
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button addTarget:self
                   action:@selector(showFlutter)
         forControlEvents:UIControlEventTouchUpInside];
        [button setTitle:@"Show Flutter!" forState:UIControlStateNormal];
        button.backgroundColor = UIColor.blueColor;
        button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
        [self.view addSubview:button];
    }
    
    - (void)showFlutter {
        FlutterEngine *flutterEngine =
            ((SCAppDelegate *)UIApplication.sharedApplication.delegate).flutterEngine;
        FlutterViewController *flutterViewController =
            [[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];
    flutterViewController.modalPresentationStyle = UIModalPresentationFullScreen;
        [self presentViewController:flutterViewController animated:YES completion:nil];
    }
    

    3)编译成功,运行如下图:


    WechatIMG2.jpeg

    四、集成项目时遇到的问题

    1、flutter中用的某些依赖可能需要科学上网工具,比如我们的flutter模块用到了FMDB

    CocoaPods设置:

    
      export http_proxy=http://xxx
      export https_proxy=https://xxx
    

    git设置:

      git config --global http.proxy http://xxx
      git config --global https.proxy https://xxx
    

    2、第三方库冲突

    比如flutter中依赖Reachability,原生中也依赖Reachability,如果它们版本不一致,则会发生冲突,可以将flutter和原生中依赖的Reachability版本改为一致

    3、路由设置不生效,一直是默认的"/"

    参考https://github.com/flutter/flutter/issues/27216中的解决方法,如下:

    • FlutterEngine will run before you create FlutterViewController so you cannot setInitialRoute.
    • To solve, you must remove that line in AppDelegate, init FlutterViewController without FlutterEngine let flutterViewController = FlutterViewController(nibName: nil, bundle: nil), and setInitialRoute, final call flutterEngine?.run(withEntrypoint: nil).

    相关文章

      网友评论

        本文标题:2020最新flutter模块集成到原生iOS项目(一)

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