美文网首页
Flutter初探--iOS项目集成flutter

Flutter初探--iOS项目集成flutter

作者: 我亦飘零久93 | 来源:发表于2019-10-23 16:30 被阅读0次

    本篇为iOS集成flutter学习总结,由flutter官方提供的最新集成方案翻译而来。本篇以OC项目为示例,Swift项目和Android项目可查看《flutter官方提供的集成方案》

    创建flutter module

    假设我们已经有了一个iOS项目,路径为 some/path/MyApp,那我们要在同级目录下创建 flutter module

    $ cd some/path/
    $ flutter create -t module my_flutter

    创建完成后,目录结构大致如下。如果目录结构不一样或者已存在.xcconfig,你可以重用,但是需要调整相对路径。

    some/path/
      my_flutter/
        lib/main.dart
        .ios/
      MyApp/
        MyApp/
          AppDelegate.h
          AppDelegate.m (or swift)
          :
    

    配置Podfile

    集成flutter需要用到CocoaPods进行依赖管理,因为flutter项目会用到很多第三方插件。

    如果你的flutter模块是在2019.7.30之前集成的,或者flutter --version小于Flutter 1.8.4-pre.21,需要升级flutter环境,并确保环境在 master channel 上才能按下边方式进行配置。

    1.配置路径

    flutter_application_path = 'path/to/my_flutter/'
    load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')

    2.给需要用到flutter的Target添加 install_all_flutter_pods(flutter_application_path)

    target 'MyApp' do
    install_all_flutter_pods(flutter_application_path)
    end
    target 'MyAppTests' do
    install_all_flutter_pods(flutter_application_path)
    end

    3.执行pod install

    若修改了 some/path/my_flutter/pubspec.yaml 的依赖配置时,需要执行flutter packages get来从podhelper.rb文件中读取依赖的插件列表,并更新依赖插件。更新完成后需要重新执行pod install

    podhelper.rb是一个ruby脚本,存放在隐藏目录.ios/Flutter/podhelper.rb下,主要作用是确保 plugins、Flutter.framework、App.framework嵌入到项目中。

    禁用BitCode

    flutter不支持bitcode,所以在项目中要设置ENABLE_BITCODE为NO,选择对应Target ,然后找到Build Settings->Build Options->Enable Bitcode改为NO即可

    image.png

    修改AppDelegate

    AppDelegate.h:

    @import UIKit;
    @import Flutter;
    
    @interface AppDelegate : FlutterAppDelegate
    @property (nonatomic,strong) FlutterEngine *flutterEngine;
    @end
    

    AppDelegate.m

    @import FlutterPluginRegistrant; // Only if you have Flutter Plugins
    
    #import "AppDelegate.h"
    
    @implementation AppDelegate
    
    // This override can be omitted if you do not have any Flutter Plugins.
    - (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      self.flutterEngine = [[FlutterEngine alloc] initWithName:@"io.flutter" project:nil];
      [self.flutterEngine runWithEntrypoint:nil];
      [GeneratedPluginRegistrant registerWithRegistry:self.flutterEngine];
      return [super application:application didFinishLaunchingWithOptions:launchOptions];
    }
    
    @end
    

    代码示例:
    ViewController.m

    #import "AppDelegate.h"
    #import "ViewController.h"
    @import Flutter;
    
    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button addTarget:self
                   action:@selector(handleButtonAction)
         forControlEvents:UIControlEventTouchUpInside];
        [button setTitle:@"Press me" forState:UIControlStateNormal];
        [button setBackgroundColor:[UIColor blueColor]];
        button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
        [self.view addSubview:button];
    }
    
    - (void)handleButtonAction {
        FlutterEngine *flutterEngine = [(AppDelegate *)[[UIApplication sharedApplication] delegate] flutterEngine];
        FlutterViewController *flutterViewController = [[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];
        [self presentViewController:flutterViewController animated:false completion:nil];
    }
    @end
    

    遇到问题

    /Users/XXX/Library/Developer/Xcode/DerivedData/ProjectName-cejmlibicqxhyohdriqdcchfxddj/Build/Intermediates.noindex/ProjectName.build/Debug-iphoneos/TargetName.build/Script-9C822F4939986DB4F2DD1121.sh: line 4: /Users/XXX/Desktop/Code/oa/../my_flutter/.ios/Flutter/flutter_export_environment.sh: No such file or directory

    从问题上可以看出flutter_export_environment.sh文件在对应路径下找不到,flutter_export_environment.sh其实与podhelper.rb在同一目录下,然后打开podhelper.rb可以看到 flutter_export_environment.sh的文件路径是由iOS项目根目录,相对路径和文件名拼接而成的。

    flutter_export_environment_path = File.join('${SRCROOT}', relative, 'flutter_export_environment.sh');
      script_phase :name => 'Run Flutter Build Script',
        :script => "set -e\nset -u\nsource \"#{flutter_export_environment_path}\"\n\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/xcode_backend.sh build",
        :input_files => [
          File.join('${SRCROOT}', flutter_application_path, '.metadata'),
          File.join('${SRCROOT}', relative, 'App.framework', 'App'),
          File.join('${SRCROOT}', relative, 'engine', 'Flutter.framework', 'Flutter'),
          flutter_export_environment_path
        ],
        :execution_position => :before_compile
    

    原因:最终发现我们的项目.xcworkspacexcodeproj居然不在统一目录下,导致项目根目录在更深层。

    解决方案:临时修改podhelper.rb脚本中的flutter_export_environment_path改为绝对路径,重新安装编译后正常运行,该方法只是临时解决该问题,如有最佳方案欢迎回复。

    相关文章

      网友评论

          本文标题:Flutter初探--iOS项目集成flutter

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