美文网首页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