本文共 22244 字,大约阅读时间需要 74 分钟。
人总要爱着什么,活着才有意义。
如果你是Android转iOS,或者是想开发Flutter插件,可以看看我的文章:。我就是一个Android开发,由于开发插件需要,学了部分的iOS开发的东西。
注意对比下我的环境和你的环境是否一样,有些问题在Flutter的新版本中已经被修复了。
➜ app git:(master) ✗ flutter --versionFlutter 1.9.1+hotfix.6 • channel stable • https://github.com/flutter/flutter.gitFramework • revision cc949a8e8b (3 weeks ago) • 2019-09-27 15:04:59 -0700Engine • revision b863200c37Tools • Dart 2.5.0
➜ app git:(master) ✗ flutter doctor -v [✓] Flutter (Channel stable, v1.9.1+hotfix.4, on Mac OS X 10.15 19A583, locale en-CN) • Flutter version 1.9.1+hotfix.4 at /Users/.../flutter • Framework revision cc949a8e8b (3 weeks ago), 2019-09-27 15:04:59 -0700 • Engine revision b863200c37 • Dart version 2.5.0 [✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2) • Android SDK at /Users/notzuonotdied/Library/Android/sdk • Android NDK location not configured (optional; useful for native profiling support) • Platform android-29, build-tools 29.0.2 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405) • All Android licenses accepted.[✓] Xcode - develop for iOS and macOS (Xcode 11.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 11.1, Build version 11A1027 • CocoaPods version 1.8.3[✓] Android Studio (version 3.5) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin version 40.1.2 • Dart plugin version 191.8423 • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)[!] IntelliJ IDEA Ultimate Edition (version 2019.2.3) • IntelliJ at /Applications/IntelliJ IDEA.app ✗ Flutter plugin not installed; this adds Flutter specific functionality. ✗ Dart plugin not installed; this adds Dart specific functionality. • For information about installing plugins, see https://flutter.dev/intellij-setup/#installing-the-plugins[✓] VS Code (version 1.39.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.5.1[✓] Connected device (1 available) • iPhone 11 Pro Max • 61AA9D21-B994-4FC5-9164-757EABF90190 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-1 (simulator)! Doctor found issues in 1 category.
本章节用于探讨Flutter编译产物以及其集成方式。
首先,先看看混编Flutter的目录结构,主要包含了三个部分:
➜ temp tree -L 2.├── Android # Android工程├── flutter_module│ ├── README.md│ ├── flutter_module.iml│ ├── flutter_module_android.iml│ ├── lib # Flutter源码目录│ ├── pubspec.yaml # Flutter依赖│ └── test└── iOS # iOS工程 ├── Podfile ├── Podfile.lock ├── Pods ├── iOS ├── iOS.xcodeproj └── iOS.xcworkspace9 directories, 9 files
看看编译之后会生成什么产物?
先看看flutter_module
目录的层级结构:
➜ flutter_module tree.├── README.md├── flutter_module.iml├── flutter_module_android.iml├── lib # Flutter源码│ └── main.dart ├── pubspec.lock├── pubspec.yaml # 依赖└── test └── widget_test.dart2 directories, 10 files
当我们执行Flutter build ios
会发生什么?
➜ flutter_module flutter build iosBuilding com.wtfexample.flutterModule for device (ios-release)...Found saved certificate choice "Apple Development: xxxxxxxx@gmail.com (xxxxxxxx)". To clear, use"flutter config".Signing iOS app for device deployment using developer identity: "Apple Development:xxxxxxxx@gmail.com (xxxxxxxx)"Running Xcode build... ├─Building Dart code... 20.0s ├─Generating dSYM file... 0.3s ├─Stripping debug symbols... 0.0s ├─Assembling Flutter resources... 0.7s └─Compiling, linking and signing... 3.9sXcode build done. 29.6sBuilt /Users/.../flutter_module/build/ios/iphoneos/Runner.app.
让我们来看看目录结构:
➜ flutter_module tree -da -L 2.├── .android # Android编译产物│ ├── Flutter│ ├── app│ └── gradle├── .idea│ └── libraries├── .ios # iOS编译产物│ ├── Config│ ├── Flutter│ ├── Frameworks│ ├── Pods│ ├── Runner│ ├── Runner.xcodeproj│ └── Runner.xcworkspace├── build│ ├── aot│ ├── dSYMs.noindex│ └── ios├── lib└── test- 主要是多了以下的部分:```shell.├── .android # Android编译产物├── .ios # iOS编译产物├── build│ ├── aot│ ├── dSYMs.noindex│ └── ios
这些也是我们要分析的内容啦,╮(╯▽╰)╭
➜ .ios tree ConfigConfig├── Debug.xcconfig├── Flutter.xcconfig└── Release.xcconfig0 directories, 3 files➜ Config cat Debug.xcconfig#include "Flutter.xcconfig"#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"➜ Config cat Release.xcconfig#include "Flutter.xcconfig"#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"➜ Config cat Flutter.xcconfig#include "../Flutter/Generated.xcconfig"ENABLE_BITCODE=NO # 目前Flutter不支持BitCode模式,默认关闭
值得一提的是Flutter.xcconfig
依赖了Flutter/Generated.xcconfig
,这个文件详见下面章节的分析。Flutter/Generated.xcconfig
配置了一些Flutter Module工程的关键环境变量。
➜ Flutter tree -da -L 2.├── .symlinks # 这是Flutter Module依赖的插件的路径,都是使用了Soft Link│ ├── amap_location -> /Users/.../amap_location-0.2.0│ ├── flutter_alipay -> /Users/.../flutter_alipay-0.1.2│ ├── flutter_amap -> /Users/.../flutter_amap-0.0.1│ ├── flutter_easy_nfc -> /Users/.../flutter_easy_nfc-0.0.1│ ├── flutter_statusbar -> /Users/.../flutter_statusbar-0.0.1│ ├── flutter_wechat_ble -> /Users/.../flutter_wechat_ble-0.1.4│ ├── linker -> /Users/.../linker-0.0.2│ └── mmkv_flutter -> /Users/.../mmkv_flutter-1.0.10├── App.framework # Flutter业务代码│ └── flutter_assets # Flutter依赖的静态资源,如字体、图片等。├── FlutterPluginRegistrant│ └── Classes└── engine # Flutter引擎,默认从$FlutterHome/bin/cache/artifacts复制一份。 └── Flutter.framework15 directories
这是Flutter Module依赖的插件的路径,都是使用了Soft Link。
➜ .symlinks tree.├── amap_location -> /Users/.../amap_location-0.2.0├── flutter_alipay -> /Users/.../flutter_alipay-0.1.2├── flutter_amap -> /Users/.../flutter_amap-0.0.1├── flutter_easy_nfc -> /Users/.../flutter_easy_nfc-0.0.1├── flutter_statusbar -> /Users/.../flutter_statusbar-0.0.1├── flutter_wechat_ble -> /Users/.../flutter_wechat_ble-0.1.4├── linker -> /Users/.../linker-0.0.2└── mmkv_flutter -> /Users/.../mmkv_flutter-1.0.108 directories, 0 files
Flutter业务层代码,以及一些静态资源文件。
我们可以看看flutter_assets
到底有什么东西?
➜ App.framework git:(master) ✗ tree -a -L 2.├── App├── Info.plist└── flutter_assets ├── AssetManifest.json ├── FontManifest.json ├── LICENSE ├── animations # 动画 ├── assets ├── fonts # 字体 ├── images # 图片 └── packages # packages中的一些资源6 directories, 5 files
Flutter业务层代码编译产物App.framework的一些信息,诸如版本信息、BundleId、版本号等等。
Flutter注册制,自动注册各个依赖的Flutter插件。
➜ FlutterPluginRegistrant tree -a -L 2.├── Classes│ ├── GeneratedPluginRegistrant.h│ └── GeneratedPluginRegistrant.m└── FlutterPluginRegistrant.podspec1 directory, 3 files
如下所示:
➜ FlutterPluginRegistrant cat Classes/GeneratedPluginRegistrant.m//// Generated file. Do not edit.//#import "GeneratedPluginRegistrant.h"#import#import #import #import #import #import #import #import @implementation GeneratedPluginRegistrant+ (void)registerWithRegistry:(NSObject *)registry { [AmapLocationPlugin registerWithRegistrar:[registry registrarForPlugin:@"AmapLocationPlugin"]]; [FlutterAlipayPlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterAlipayPlugin"]]; [FlutterAmapPlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterAmapPlugin"]]; [FlutterEasyNfcPlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterEasyNfcPlugin"]]; [FlutterStatusbarPlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterStatusbarPlugin"]]; [FlutterWechatBlePlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterWechatBlePlugin"]]; [LinkerPlugin registerWithRegistrar:[registry registrarForPlugin:@"LinkerPlugin"]]; [MmkvFlutterPlugin registerWithRegistrar:[registry registrarForPlugin:@"MmkvFlutterPlugin"]];}@end
这个是Flutter编译的时候自动生成的,定义了一些关键的配置。
➜ Flutter cat Generated.xcconfig// This is a generated file; do not edit or check into version control.FLUTTER_ROOT=/Users/.../1.9.1+hotfix.6-stableFLUTTER_APPLICATION_PATH=/Users/.../flutter_moduleFLUTTER_TARGET=lib/main.dartFLUTTER_BUILD_DIR=buildSYMROOT=${SOURCE_ROOT}/../build/iosFLUTTER_BUILD_NAME=1.0.0FLUTTER_BUILD_NUMBER=1
这个和Flutter/Generated.xcconfig
一样是Flutter编译生成的,用于初始化一些必须的变量。
➜ Flutter cat flutter_export_environment.sh#!/bin/sh# This is a generated file; do not edit or check into version control.export "FLUTTER_ROOT=/Users/.../1.9.1+hotfix.6-stable"export "FLUTTER_APPLICATION_PATH=/Users/.../flutter_module"export "FLUTTER_TARGET=lib/main.dart"export "FLUTTER_BUILD_DIR=build"export "SYMROOT=${SOURCE_ROOT}/../build/ios"export "FLUTTER_BUILD_NAME=1.0.0"export "FLUTTER_BUILD_NUMBER=1"
具体用处可见下面章节Flutter/podhelper.rb的install_flutter_application_pod
函数实现。
这个是直接从Flutter的SDK安装目录复制过来的,路径在$FLUTTER_ROOT/bin/cache/artifacts
。
这个是最核心的一部分,分析Flutter Module依赖的插件的依赖,
install
到Flutter的.ios
工程中。
在.ios/Podfile
中,我们看到Podfile
加载使用load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
加载了podhelper.rb
这个脚本。
➜ .ios git:(master) ✗ cat Podfileplatform :ios, '8.0'# Flutter Module的目录flutter_application_path = '../' # 这里的podhelper.rb就是.ios/Flutter/podhelper.rbload File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')# install依赖target 'Runner' do # 函数,定义在podhelper.rb install_flutter_engine_pod # 函数,定义在podhelper.rb install_flutter_plugin_pods flutter_application_path end# 在pod install的最后一步,执行某些配置post_install do |installer| installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['ENABLE_BITCODE'] = 'NO' # Flutter默认不支持BitCode end endend# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.install! 'cocoapods', :disable_input_output_paths => true
这个脚本其实就如下图所示的流程。
下面,我们来分析下Flutter/podhelper.rb
:
这个是一个入口函数,包含了几个函数:
# Install pods needed to embed Flutter application, Flutter engine, and plugins# from the host application Podfile.## @example# target 'MyApp' do# install_all_flutter_pods 'my_flutter'# end# @param [String] flutter_application_path Path of the root directory of the Flutter module.# Optional, defaults to two levels up from the directory of this script.# MyApp/my_flutter/.ios/Flutter/../..def install_all_flutter_pods(flutter_application_path = nil) # 跳两级出去,即Flutter工程根目录 flutter_application_path ||= File.join('..', '..') # 添加Flutter Engine依赖 install_flutter_engine_pod # 添加Flutter插件的依赖 install_flutter_plugin_pods(flutter_application_path) # 添加Flutter业务代码的依赖 install_flutter_application_pod(flutter_application_path)end
# Install Flutter engine pod.## @example# target 'MyApp' do# install_flutter_engine_pod# enddef install_flutter_engine_pod # 核心工作,复制Flutter的引擎到工程目录下。 engine_dir = File.join(__dir__, 'engine') if !File.exist?(engine_dir) # Copy the debug engine to have something to link against if the xcode backend script has not run yet. # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. debug_framework_dir = File.join(flutter_root, 'bin', 'cache', 'artifacts', 'engine', 'ios') # 创建目录并拷贝引擎 FileUtils.mkdir_p(engine_dir) FileUtils.cp_r(File.join(debug_framework_dir, 'Flutter.framework'), engine_dir) FileUtils.cp(File.join(debug_framework_dir, 'Flutter.podspec'), engine_dir) end # Keep pod path relative so it can be checked into Podfile.lock. # Process will be run from project directory. engine_pathname = Pathname.new engine_dir project_directory_pathname = Pathname.new Dir.pwd relative = engine_pathname.relative_path_from project_directory_pathname pod 'Flutter', :path => relative.to_s, :inhibit_warnings => trueend
debug_framework_dir = File.join(flutter_root, 'bin', 'cache', 'artifacts', 'engine', 'ios')
指向的目录是Flutter引擎的目录,可以看看$FlutterRoot/bin/cache/artifacts/engine
这个目录:
➜ 1.9.1+hotfix.6-stable git:(stable) ✗ tree bin/cache/artifacts/engine -L 1 | grep ios├── ios│ ├── Flutter.framework│ ├── Flutter.framework.zip│ ├── Flutter.podspec│ ├── LICENSE│ ├── gen_snapshot_arm64│ └── gen_snapshot_armv7├── ios-profile│ ├── Flutter.framework│ ├── Flutter.framework.zip│ ├── Flutter.podspec│ ├── LICENSE│ ├── gen_snapshot_arm64│ └── gen_snapshot_armv7└── ios-release ├── Flutter.framework ├── Flutter.framework.zip ├── Flutter.podspec ├── LICENSE ├── gen_snapshot_arm64 └── gen_snapshot_armv7
# Install Flutter plugin pods.## @example# target 'MyApp' do# install_flutter_plugin_pods 'my_flutter'# end# @param [String] flutter_application_path Path of the root directory of the Flutter module.# Optional, defaults to two levels up from the directory of this script.# MyApp/my_flutter/.ios/Flutter/../..def install_flutter_plugin_pods(flutter_application_path) # 核心工作,增加Flutter插件注册FlutterPluginRegistrant库(自动生成并注册Flutter Channel) # 分析插件的依赖并创建插件的依赖的软链接到.symlinks目录下。 flutter_application_path ||= File.join('..', '..') # Keep pod path relative so it can be checked into Podfile.lock. # Process will be run from project directory. current_directory_pathname = Pathname.new __dir__ project_directory_pathname = Pathname.new Dir.pwd relative = current_directory_pathname.relative_path_from project_directory_pathname pod 'FlutterPluginRegistrant', :path => File.join(relative, 'FlutterPluginRegistrant'), :inhibit_warnings => true symlinks_dir = File.join(relative, '.symlinks') FileUtils.mkdir_p(symlinks_dir) plugin_pods = parse_KV_file(File.join(flutter_application_path, '.flutter-plugins')) plugin_pods.map do |r| symlink = File.join(symlinks_dir, r[:name]) FileUtils.rm_f(symlink) File.symlink(r[:path], symlink) pod r[:name], :path => File.join(symlink, 'ios'), :inhibit_warnings => true endend
FlutterPluginRegistrant
这个的生成可见,我们先看看.flutter-plugins
:➜ flutter_module cat .flutter-pluginsamap_location=/.../1.9.1+hotfix.6-stable/.pub-cache/.../amap_location-0.2.0/flutter_alipay=/.../1.9.1+hotfix.6-stable/.pub-cache/.../flutter_alipay-0.1.2/flutter_amap=/.../1.9.1+hotfix.6-stable/.pub-cache/.../flutter_amap-0.0.1/flutter_easy_nfc=/.../1.9.1+hotfix.6-stable/.pub-cache/.../flutter_easy_nfc-0.0.1/flutter_statusbar=/.../1.9.1+hotfix.6-stable/.pub-cache/.../flutter_statusbar-0.0.1/flutter_wechat_ble=/.../1.9.1+hotfix.6-stable/.pub-cache/.../flutter_wechat_ble-0.1.4/linker=/.../1.9.1+hotfix.6-stable/.pub-cache/.../linker-0.0.2/mmkv_flutter=/.../1.9.1+hotfix.6-stable/.pub-cache/.../mmkv_flutter-1.0.10/
由此可见,这里保存了Flutter工程依赖的插件的本地缓存目录。
# Install Flutter application pod.## @example# target 'MyApp' do# install_flutter_application_pod '../flutter_settings_repository'# end# @param [String] flutter_application_path Path of the root directory of the Flutter module.# Optional, defaults to two levels up from the directory of this script.# MyApp/my_flutter/.ios/Flutter/../..def install_flutter_application_pod(flutter_application_path) # 编译Flutter的业务层代码并依赖到主工程。 app_framework_dir = File.join(__dir__, 'App.framework') app_framework_dylib = File.join(app_framework_dir, 'App') if !File.exist?(app_framework_dylib) # Fake an App.framework to have something to link against if the xcode backend script has not run yet. # CocoaPods will not embed the framework on pod install (before any build phases can run) if the dylib does not exist. # Create a dummy dylib. FileUtils.mkdir_p(app_framework_dir) `echo "static const int Moo = 88;" | xcrun clang -x c -dynamiclib -o "#{ app_framework_dylib}" -` end # Keep pod and script phase paths relative so they can be checked into source control. # Process will be run from project directory. current_directory_pathname = Pathname.new __dir__ project_directory_pathname = Pathname.new Dir.pwd relative = current_directory_pathname.relative_path_from project_directory_pathname pod 'flutter_app', :path => relative.to_s, :inhibit_warnings => true # 读取flutter_export_environment.sh,并提供必要的环境变量 flutter_export_environment_path = File.join('${SRCROOT}', relative, 'flutter_export_environment.sh'); # 最关键的一步,涉及到了xcode_backend.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_compileend
"$FLUTTER_ROOT\"/packages/flutter_tools/bin/xcode_backend.sh
看看File.join('${SRCROOT}', flutter_application_path, '.metadata'),
这里的'.metadata'
:
➜ flutter_module ✗ cat .metadata# This file tracks properties of this Flutter project.# Used by Flutter tool to assess capabilities and perform upgrades etc.## This file should be version controlled and should not be manually edited.version: revision: 5391447fae6209bb21a89e6a5a6583cac1af9b4b channel: stableproject_type: module
这里存放的是工程依赖的Flutter tool版本。
# 分析Generated.xcconfig等配置文件def parse_KV_file(file, separator='=') file_abs_path = File.expand_path(file) if !File.exists? file_abs_path return []; end pods_array = [] skip_line_start_symbols = ["#", "/"] File.foreach(file_abs_path) { |line| next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } plugin = line.split(pattern=separator) if plugin.length == 2 podname = plugin[0].strip() path = plugin[1].strip() podpath = File.expand_path("#{ path}", file_abs_path) pods_array.push({ :name => podname, :path => podpath}); else puts "Invalid plugin specification: #{ line}" end } return pods_arrayend
# 分析Generated.xcconfig找到FLUTTER_ROOT地址# FLUTTER_ROOT指的是Flutter SDK的路径def flutter_root generated_xcode_build_settings = parse_KV_file(File.join(__dir__, 'Generated.xcconfig')) if generated_xcode_build_settings.empty? puts "Generated.xcconfig must exist. Make sure `flutter pub get` is executed in the Flutter module." exit end generated_xcode_build_settings.map { |p| if p[:name] == 'FLUTTER_ROOT' return p[:path] end }end
函数 | 作用 |
---|---|
install_all_flutter_pods | 入口函数,跳转到Flutter工程根目录,添加Flutter Engine依赖、Flutter插件依赖、Flutter业务层代码依赖。 |
install_flutter_engine_pod | 复制Flutter Debug版本的引擎到工程目录下,位于.ios/Flutter 。 |
install_flutter_plugin_pods | 生成Flutter插件的注册库并依赖,分析各个Flutter插件的依赖,并创建依赖库的软链接到.symlinks 目录下,即注册插件、分析依赖并依赖到主工程。 |
install_flutter_application_pod | 编译Flutter 业务层代码到App.framework,并依赖到主工程。 |
parse_KV_file | 分析Generated.xcconfig 等配置文件,用于插件依赖分析。 |
flutter_root | 分析Generated.xcconfig 找到FLUTTER_ROOT 地址,FLUTTER_ROOT 指的是Flutter SDK的路径。 |
这个目录存放的是Flutter插件依赖的库。
➜ .ios tree -L 1 PodsPods├── AMap3DMap├── AMapFoundation├── AMapLocation├── AliPay├── Headers # 头文件*.h├── Local\ Podspecs # Flutter插件的PodSpec├── MMKV├── Manifest.lock # 即Podfile.lock,保存了依赖的版本和地址等信息├── Pods.xcodeproj└── Target\ Support\ Files # 存放Flutter插件依赖的库的一些配置文件9 directories, 1 file
分为Private
和Public
分别存放依赖库的头文件。
➜ .ios tree -L 2 Pods/HeadersPods/Headers├── Private│ ├── FlutterPluginRegistrant│ ├── MMKV│ ├── amap_location│ ├── flutter_alipay│ ├── flutter_amap│ ├── flutter_easy_nfc│ ├── flutter_statusbar│ ├── flutter_wechat_ble│ ├── linker│ └── mmkv_flutter└── Public ├── FlutterPluginRegistrant ├── MMKV ├── amap_location ├── flutter_alipay ├── flutter_amap ├── flutter_easy_nfc ├── flutter_statusbar ├── flutter_wechat_ble ├── linker └── mmkv_flutter22 directories, 0 files
在Flutter工程中,直接在pubspec.yaml依赖了插件,在执行flutter build ios
的时候,就会执行flutter pub get
和flutter package get
,将Flutter插件下载到本地,最后Flutter插件的podspec会被自动转换为podspec.json,并存放在.ios/Pods/Local Podspecs
中。
➜ .ios tree -L 1 Pods/Local\ PodspecsPods/Local\ Podspecs├── Flutter.podspec.json├── FlutterPluginRegistrant.podspec.json├── amap_location.podspec.json├── flutter_alipay.podspec.json├── flutter_amap.podspec.json├── flutter_easy_nfc.podspec.json├── flutter_statusbar.podspec.json├── flutter_wechat_ble.podspec.json├── linker.podspec.json└── mmkv_flutter.podspec.json0 directories, 10 files
存放Flutter插件依赖的库的一些配置文件。
➜ .ios tree -L 1 Pods/Target\ Support\ FilesPods/Target\ Support\ Files├── AMap3DMap├── AMapFoundation├── AMapLocation├── AliPay├── Flutter├── FlutterPluginRegistrant├── MMKV├── Pods-Runner├── amap_location├── flutter_alipay├── flutter_amap├── flutter_easy_nfc├── flutter_statusbar├── flutter_wechat_ble├── linker└── mmkv_flutter16 directories, 0 files
flutter build ios --release
后的一些关键编译产物为:
产物 | 介绍 |
---|---|
App.framework | Dart业务源码相关文件,在Debug模式下就是一个很小的空壳,在Release模式下包含全部业务逻辑。 |
flutter_assets | Flutter依赖的静态资源,如字体、图片等。在Flutter 1.9.1这种已经被合并进App.framework。 |
FlutterPluginRegistrant | Flutter插件注册制,自动注册Flutter插件。 |
Flutter.framework | Flutter库和引擎。 |
.symlinks | 指向Flutter插件依赖库的实际地址。 |
因此,实际上Native接入Flutter的需要的就是接入以上的产物,其中flutter build ios
生成的产物Generated.xcconfig、flutter_export_environment.sh为编译提供了必要的参数。
转载地址:http://xqzrj.baihongyu.com/