我们知道要想在原生工程集成Flutter module时,如果使用 CocoaPods 管理依赖和已安装的 Flutter SDK?,需要在pod文件中添加
flutter_application_path = './flutter_module'
load File.join(flutter_application_path, ‘.ios’, ‘Flutter’, ‘podhelper.rb’)
这两行代码,然后在target中添加一行:
install_all_flutter_pods(flutter_application_path)
(不知道的可以看这里)
那么这几行代码究竟起到了什么作用呢??
首先我们来解读一下前两行代码:
- flutter_application_path = './flutter_module' 这是给flutter_application_path变量赋值了当前flutterModule的目录,也就是我们要导入项目的flutter模块,比较容易理解。
- load File.join(flutter_application_path, ‘.ios’, ‘Flutter’, ‘podhelper.rb’) 这行呢,这是一条ruby的语法,简单的意思是返回一个字符串,由指定的项连接在一起,并使用文件分割符进行分隔。
File.join(flutter_application_path, ‘.ios’, ‘Flutter’, ‘podhelper.rb’) ?==>>?"flutter_application_path/.ios/Flutter/podhelper.rb"。 load则是引入该文件,可以理解为将podhelper.rb文件导入进来。
下面的一行是什么意思呢?我们先打开看看podhelper.rb这个文件的内容。
?先看第一段代码,眼熟吗?这不就是我们在pods文件中输入的代码吗?
install_all_flutter_pods(flutter_application_path)
- 第一行的 def 是ruby语法中的定义一个函数的意思,()括号中是参数,flutter_application_path =nil 是给参数赋了一个默认值,end是该函数的结束
- 第二行flutter_application_path ||= File.join('..', '..')? ? ?
- "||=" 的意思是?如果?flutter_application_path这个变量没有值就给他赋值后面的内容 类似于Dart语法中的 "??="
- 3-5行则是分别调用了3个别的函数我们接下来一一看一下。
第一函数:install_flutter_engine_pod
通过函数名字install_flutter_engine_pod猜一下这应该是载入flutter引擎的函数
- 第31行(左边标识了行数) File.expand_path('..', __FILE__) 这也是ruby的语法,__FILE__表示当前文件,..表示上一级目录,.expand_path表示返回后面参数的绝对路径,也就该文件(podhelper.rb)的所在目录的绝对路径。
- 第32行?engine_dir = File.expand_path('engine', current_directory),返回了engine目录的绝对路径。
- 第33 34行 framework_name = 'Flutter.xcframework'? ?copied_engine = File.expand_path(framework_name, engine_dir),返回了Flutter.xcframework的绝对路径。
- ?第35-44行是一个判断语句块,如果copied_engine这个文件不存在则会进入,会找到并从fluttterSDK中将Flutter.xcframework拷贝到copied_engine这里
- 第38行release_framework_dir = File.join(flutter_root, 'bin', 'cache', 'artifacts', 'engine', 'ios-release')中的flutter_root函数(如下图)
该函数是搜索Generated.xcconfig文件(不在就会抛出一个异常)然后将FLUTTER_ROOT目录读取出来,读取不到也会抛出异常。这里有一个unless语法,和if是相反的意思,如果unless后面的条件不满足则会进入。
- 第39-41行,如果fluttersdk中的引擎文件(Flutter.xcframework)也找不到,就会抛出异常。
- 第43行FileUtils是ruby中可以使用linux的语法的工具集,这行是如果找到了Flutter.xcframework就拷贝到之前的目录。
- 第48行engine_pathname = Pathname.new engine_dir。? Pathname?路径名表示文件系统上文件或目录的名称,但不表示文件本身。这个类的目标是以比Ruby标准提供的更简洁的方式处理文件路径信息。这句语句可以理解为创建了一个"目录"对象,该对象表示的目录是engine_dir。
- 第50行的意思可以参考49行的注释,拿到了pod文件所在的路径
- 第51行 前面的engine_pathname是一个目录对象,这里使用了它的一个函数.relative_path_from是拿到两个目录之间的相对路径,例子如下
p1 = Pathname.new("/usr/lib/test") /usr/lib/test
p2 = Pathname.new("/usr") /usr
p3 = p2.relative_path_from(p1) lib/test
- 第53行 这个应该熟悉了 就是pod导入。relative.to_s? 中的.to_s是将目录对象转化为字符串。ruby中定义的任何类都有一个?to_s?实例方法来返回对象的字符串表示形式。
第二个函数:install_flutter_plugin_pods(flutter_application_path)
- 第66行上面解释过了,是容错处理
- 第70-74行是找到FlutterPluginRegistrant的相对路径然后pod导入
- 第77行表示创建76行的目录
- 第80行有一个flutter_parse_dependencies_file_for_ios_plugin(file)函数(如下图)
?先是一些容错处理。文件不存在返回空;没有"plugins"这个key返回空;最后将指定的数组取出。
- 第81-88行是遍历plugin_pods并一一pod导入。
第三个函数:install_flutter_application_pod(flutter_application_path)
?
- 第103-111行是找到App.framework下的App,如果找不到则抛出异常。?
- 118-120行是找到flutterMoudle中的Flutter目录相对于工程的相对路径然后pod导入
- 122行和123行要特别注意的地方:这里的代码原本是122行,但是项目执行的时候会报找不到flutter_export_environment.sh文件的错误,这里根据实际位置做了相应调整为123行。
- 124行,眼熟的地方又来了。我们知道pod倒入flutterModule的时候,在Xcode的build Phases里会多出一个脚本
- 这里的代码就是负责这块的。
- 第126行execution_position => :before_compile 表示脚本在编译前执行。
总结:?
我们看懂了这个pobhelper.rb脚本之后,如果发生什么目录配置错误,就知道该去哪里看了,还是挺有帮助的。这个文件在我们pod install的时候会执行,然后将flutter engine,flutter plugin,flutter module代码导入我们的工程。
?
|