Code前端首页关于Code前端联系我们

如何编写一个自动将Flutter打包成iOS代码模块的脚本

terry 2年前 (2023-09-23) 阅读数 77 #移动小程序

解决方案选择

经过探索并结合项目现状(我们公司的项目采用模块化开发,与Pod集成),有以下几种两种解决方案:

  • 使用Google的集成方案
  • 将Flutter编译后的产品打包到一个新的子模块中,并在其中实现相应的接口和交互逻辑。

无论是从易用性还是破解代码的程度来看,采用方案2都是顺理成章的。步骤(实际收集组装好的产品)

包装步骤

包装步骤如下:

1.颤动构建ios。

2。进入Flutter项目对应的../ios(或.ios)/Flutter/文件夹,找到app.framework、Flutter.framework和FlutterPluginRegistrant文​​件夹,将其复制到子模块中。

3。进入Flutter工程对应的build/ios/debug-iphoneos(或release-iphoneos),将各个依赖库的.a文件复制到子模块中。

4。如果项目依赖了第三方插件(一般都有),则必须根据.flutter中的路径将各个依赖库的.h复制到对应模块源码的ios/classes下。 - 插件文件。文件(这一步可以说是相当繁琐)。

使用自动化脚本执行以上操作

以下代码在Flutter工程目录下操作(请确保Flutter插件没有源码依赖):

首先是打包:

echo "===清理flutter历史编译==="
flutter clean

echo "===重新生成plugin索引==="
flutter packages get

echo "===生成App.framework和flutter_assets==="
flutter build ios --debug
# 或者 flutter build ios --release
复制代码

然后复制App.framework和Flutter.framework:

framework_dir=...
echo "===copy App.framework和Flutter.framework==="
cp -r "./.ios/Flutter/App.framework" $framework_dir
cp -r "./.ios/Flutter/engine/Flutter.framework" $framework_dir
复制代码

复制Registrar:

classes_dir=...
echo "===copy注册器:FlutterPluginRegistrant==="
regist_dir="./.ios/Flutter/FlutterPluginRegistrant/Classes/"
model_class=${classes_dir}/flutter/FlutterPluginRegistrant
mkdir -p $model_class
cp -r $regist_dir $model_class
复制代码

接下来是各个插件的复制。这里有一点挖掘。由于每个插件都是打包导入为.a形式的,所以很可能会导致模拟器崩溃。使用过程中调试的模拟器:

# 合成的.a文件缓存
    temp_dir=...
    mkdir -p ${temp_dir}
    
current_path="$PWD"
# 执行clean并重新编译pods部分
cd .ios/Pods
    /usr/bin/env xcrun xcodebuild clean
    /usr/bin/env xcrun xcodebuild build -configuration Release ARCHS='arm64 armv7' BUILD_AOT_ONLY=YES VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner BUILD_DIR=../build/ios -sdk iphoneos
    
# 遍历.flutter-plugins文件
cat .flutter-plugins | while read line
    do
    array=(${line//=/ })
        plugin_name=${array[0]}
        echo "===修改注册器(修正引用)==="
        perl -pi -e "s|\<${plugin_name}\/|\"|g" ${model_class}/GeneratedPluginRegistrant.m
        perl -pi -e "s|.h\>|.h\"|g" ${model_class}/GeneratedPluginRegistrant.m
        temp_library=${temp_dir}/lib${plugin_name}.a
        echo ">>>生成lib${plugin_name}.a<<<"
        cd .ios/Pods
        /usr/bin/env xcrun xcodebuild build -configuration Release ARCHS='arm64 armv7' -target ${plugin_name} BUILD_DIR=../../build/ios -sdk iphoneos -quiet
        /usr/bin/env xcrun xcodebuild build -configuration Debug ARCHS='x86_64' -target ${plugin_name} BUILD_DIR=../../build/ios -sdk iphonesimulator -quiet
        echo ">>>合并lib${plugin_name}.a<<<"
        lipo -create "../../build/ios/Debug-iphonesimulator/${plugin_name}/lib${plugin_name}.a" "../../build/ios/Release-iphoneos/${plugin_name}/lib${plugin_name}.a" -o $temp_library
        cd $current_path
        if [[ -f "$temp_library" ]]; then
            echo "===copy ${plugin_name}==="
            plugin=${framework_dir}/${plugin_name}
            rm -rf $plugin
            mkdir -p $plugin
            cp -f $temp_library $plugin
            classes=${array[1]}ios/Classes
            class=$dest_dir/Classes/flutter/${plugin_name}
            rm -rf $class
            mkdir -p $class
            for header in `find "$classes" -name *.h`; do
                cp -f $header $class
            done
        fi
    done
    rm -rf ${temp_dir}
fi
复制代码

也许你注意到上面的===更改寄存器的内容(更正引用)===。这是因为我们把Flutter插件部分的文件直接打包成静态库,并将其所有.h文件导入到模块中,所以是自动生成的#import 模式不适用(报错),必须以#import "xxx.h"的形式引用。

至此,Flutter的自动打包脚本就基本完成了。上面各个文件路径一定要根据当前情况进行调整,改为适合自己项目的路径。

作者:gzhong Cheng
链接:https://juejin.im/post/5cf734a6f265da1b6d401311
来源:掘金归属作者所有。如需商业转载,请联系求作者授权。非商业转载请来源。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门