在iOS工程与Flutter混编

前言 前段时间简单看了一下flutter,其中的一个步骤和遇到的一些坑分享一下。
版本为1.9.1+hotfix6
1.安装Flutter 下载最新flutter安装包 下载最新安装包并解压到你想安装的路径。
安装包下载地址:flutter官方下载地址
添加flutter工具到path中(添加环境到.bash_profile)

  • 打开(或者创建)$HOME/.bash_profile 文件路径和文件名可能在您的机器上不同
    如果出现permission deny 用vim ~/.bash_profile (如果存在则输入e进行编辑模式)输入i编辑添加以下内容后按esc退出后:wq进行保存。
  • 添加以下行并更改[PATH_TO_FLUTTER_GIT_DIRECTORY]为克隆Flutter的git repo的路径
    export PUB_HOSTED_URL=https://pub.flutter-io.cn //国内用户需要设置
    export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn //国内用户需要设置
    export PATH=PATH_TO_FLUTTER_GIT_DIRECTORY/flutter/bin:PATH
  • 运行 source $HOME/.bash_profile 刷新当前终端窗口
    如果你使用的是zsh,终端启动时~/.bash_profile 将不会被加载,解决办法就是修改 ~/.zshrc文件 ,在其中添加:source ~/.bash_profile
  • 通过运行命令验证目录是否在已经在PATH中
    在终端输入echo $PATH即可验证
  • 验证安装成功
    输入flutter doctor安装必要的依赖项,完成后输入flutter version查看版本 检测环境是否配置成功。
    注意:
    1.9.1版本打包有可能出现 Flutter.framework: Permission denied
    如果是这个版本,则需要替换掉flutter安装目录下的flutter/packages/flutter_tools/bin/xcode_backend.sh文件里面的114行
    RunCommand find " {derived_dir}/engine/Flutter.framework" -type f -iname '.h' -exec chmod a-w "{}" ;
iOS混编Flutter(具体可参考配置工程文档) 配置好之后就可以开始项目,如果你需要创建一个flutter混编项目,cd到你要创建flutter的目录,然后执行flutter create -t module my_flutter(my_flutter就是你的flutter的目录)。
参考:https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps
中文参考:https://blog.csdn.net/studying_ios/article/details/98872913
2.配置iOS工程 前言 原生工程和flutter工程各自独立,原生项目可引入flutter工程混编。
注意:两个项目工程必须在同一个文件夹里面而且同级。
下载工程 我们先把原生工程拉取下来放在对应的目录下面,需要注意的是flutter的目录和原生工程目录需要同一级,开发人员都保持路径层级统一(也可不同路径层级,但是需要额外修改原生.sh的路径,另外还需要修改podfile,对于其他人使用你的flutter工程,不同层级可能报第三方库替身文件引用失败问题)。
参考示例:

在iOS工程与Flutter混编
文章图片
工程文件夹 如果原生工程还没有配置过flutter工程,需要配置。
打开终端cd到原生工程的上级目录,如上图ios_workspace的上一级目录下。
然后执行flutter create -t module my_flutter(my_flutter是你flutter项目名字,可更改)。
这样同级目录下就会生成一个my_flutter的目录了,可参考:
Add Flutter to existing apps
添加flutter到已存在的ios项目中文版
获取依赖库 一般flutter项目也会引入各种第三方的package依赖包,并且这个包是通过替身文件指向你安装flutter中的.pub-cache(这个目录是隐藏文件)目录下,所以需要先获取到这些包。
cd到flutter目录执行flutter packages get
也可用AS打开pubspec.yaml,点击右上角的packages get
执行完后这些库就下载在flutter的安装目录下面了。
配置原生工程podfile文件 项目需要引入pod,通过pod来集成flutter
你flutter工程路径 最好和工程在同一个文件夹
对于需要自己配置的项目在podflie中添加:
flutter_application_path = '../space_flutter/' #flutter_application_path
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
然后在需要的target下添加:
install_all_flutter_pods(flutter_application_path)
如下图:

在iOS工程与Flutter混编
文章图片
podfile文件 添加完成之后再执行pod install就可以运行项目了。
如果路径出错,检查一下路径,当然也可换成绝对路径试试。
notice:
以上基本可以运行成功,但纳米盒工程.xcodeproj文件深一层,
所以每次pod install之后sh文件路径指向出错修复可看下面报错处理第二条。
搭建模块组件 如果想把flutter module独立出来,可打成组件使用,其他开发人员不需要安装flutter环境。具体可参考Flutter打包文档。
可能报错
  • podhelper.rp文件查找失败,这个是podfile中flutter_application_path文件路径出错,检查一下其对应的路径是否有对
  • flutter_export_enviroment.sh报错,在你工程中去查看一下路径是否正确。查找如下图:(../表示上一级目录)

    在iOS工程与Flutter混编
    文章图片
    原生工程配置
  • 第三方库path_provider等引入失败
    Flutter的第三方package资源在安装Flutter路径下面的/.pub-cache/hosted/里面,而项目中引入的第三方package是通过替身文件(替身路径/.ios/Flutter/.symlinks/)指向的,有可能这个替身文件指向出错,需要去检查一下,如果出现这种错误,需要你删掉flutter工程再重新生成原flutter工程,工程名和之前一样,记得把lib、pubspec.yaml等其他可提交的文件备份一份,生成后替换再重新拉取第三方库后pod install一下。
3.iOS打包flutter Flutter module可以打包成单独的framework供原生app调用。
生成打包的framework文件(release包) 使用flutter_framework_pack.sh脚本可一键打包。(可在共享文件IT/终端下载)
把sh文件放在你创建的flutter工程目录下,执行.sh脚本。
在终端中cd到脚本所在路径,然后终端执行
./ flutter_framework_pack .sh。
如果出现permission denied:提示
可输入 chmod 777 flutter_framework_pack .sh
再次执行脚本文件。
这是release模式的包,如需要debug则可修改文件中
flutter build ios --release --no-codesign
的release模式改为
flutter build ios --debug --no-codesign
脚本介绍可参考:把flutter作为framework添加到iOS项目中
对应会在目录下生成一个framework的文件夹,我们不必上传到gitlab上,可修改.ignore(隐藏文件)设置为忽略提交
pod集成(本地pod) 在项目根目录(也可在其他目录,测试项目是在根目录的LocalPods目录下)新建一个文件夹(例如flutterTest)。
把第一步得到的framework放到这个目录下。
创建一个flutterTest.podspec文件(共享目录IT/终端有一个podspec文件,可参考)
s.ios.vendored_frameworks = 'App.framework', 'Flutter.framework'
修改为你生成的framework文件。
然后终端cd到这个目录下执行
pod lib linit --allow-warnings。
然后就可以在项目对应的target中引入了
pod 'flutterTest', :path=> './LocalPods/flutterTest'
最后cd到项目目录执行一下pod install就可以使用了
4.flutter在iOS中的坑点
  • flutter里面如果model里面属性其他model,需要对model为空的情况处理,否则null.null会运行出错。
  • flutter第三框库更新或增加其他package,除package get之外还需要再pod install一下。
  • pubspec.yaml dependencies:格式要对,注意对齐。
  • ios通过methodChannel通道传json数据给flutter不需要转码(urlencode),不然json.decode(jsonString)会失败。
  • 【在iOS工程与Flutter混编】CachedNetworkImage混编工程不显示图片,需要VC注册一下[GeneratedPluginRegistrant registerWithRegistry:testVC];

    推荐阅读