1.這里創建一個Flutter項目(App)
- 使用Xcode打開其中的iOS工程
- 打開
Generated.xcconfig
添加環境變量
//添加環境變量
//1.引擎代碼的src路徑
FLUTTER_ENGINE=/Users/mac/Desktop/Flutter-Engine/engine_download/src
//2.使用引擎對應版本,模擬器版本
LOCAL_ENGINE=ios_debug_sim_unopt
- Command+R運行該iOS項目
2. 工程關聯過程(Xcode->Dart)
- iOS腳本配置在
Target->Build Phases->Run Script
中
/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
- 進入
$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh
($FLUTTER_ROOT
為FlutterSDK位置) xcode_backend.sh
#!/usr/bin/env bash
# Copyright 2014 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# exit on error, or usage of unset var
set -euo pipefail
# Needed because if it is set, cd may print the path it changed to.
unset CDPATH
function follow_links() (
cd -P "$(dirname -- "$1")"
file="$PWD/$(basename -- "$1")"
while [[ -h "$file" ]]; do
cd -P "$(dirname -- "$file")"
file="$(readlink -- "$file")"
cd -P "$(dirname -- "$file")"
file="$PWD/$(basename -- "$file")"
done
echo "$file"
)
PROG_NAME="$(follow_links "${BASH_SOURCE[0]}")"
BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
FLUTTER_ROOT="$BIN_DIR/../../.."
DART="$FLUTTER_ROOT/bin/dart"
"$DART" "$BIN_DIR/xcode_backend.dart" "$@"
-
xcode_backend.sh
沒有使用到Generated.xcconfig
文件中的環境變量 - xcode工程執行了這個腳本后,然后執行到了
xcode_backend.dart
這個文件
- 進入
xcode_backend.dart
文件,之前的環境變量在這個文件使用到了。具體代碼太長就沒有貼出來
3.證明運行的iOS項目與我自己的渲染引擎已經關聯
- 1.在運行中的項目下一個斷點
touchesBegan:withEvent:
br set -n "touchesBegan:withEvent:"
- 2.點擊屏幕,過掉一些UI相關的斷點后,進入
FlutterViewController.mm
斷點
touchBegan_breakpoint.png - 3.在
touchesBegan
添加打印語句
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
NSLog(@"123");
[self dispatchTouches:touches pointerDataChangeOverride:nullptr event:event];
}
- 4.通過
Command+j
查看不到FlutterViewController.mm
文件所在位置 - 5.猜測
FlutterViewController.mm
是在Flutter引擎代碼里,打開ios_debug_sim_unopt
工程查看
flutter_engin_code.png
1.這里可以清晰的看到,剛才寫的打印語句在Flutter引擎代碼里面
2.此時Xcode工程和FLutter渲染引擎已經關聯起來了
4.為什么點擊屏幕控制臺不執行打印語句?
- 原因其實很簡單,當我們引擎改了代碼,需要使用
ninja
去編譯一次 - Xcode工程使用的是Flutter.framework,因此修改后必須編譯一次更新Flutter.framework
mac@mac out % ninja -C host_debug_unopt && ninja -C ios_debug_sim_unopt
ninja: Entering directory `host_debug_unopt'
ninja: no work to do.
ninja: Entering directory `ios_debug_sim_unopt'
[16/16] STAMP obj/default.stamp
- Xcode工程停掉,再運行
- 點擊模擬器屏幕,此時打印輸出正常
5.原理剖析
- 此時查看
FlutterViewController.mm
文件所在位置 - 你會驚訝的發現
FlutterViewController.mm
文件不在ios_debug_sim_unopt
目錄下 - 路徑為
/src/flutter/shell/platform/darwin/ios/framework/Source
-
源碼存放的位置并不在編譯后的文件內,而是在引擎源碼的其它目錄下
總結 因此并不是每編譯一次模擬器/真機(release/debug),就會重新生成一份源碼
它是根據同一份源碼編譯出不同的產物
6.md5檢查Flutter.framework
-
比對4次Flutter.framework的md5值(2次自定義版本,2次發布版本)
Product_flutterframework.png - 1.
Generated.xcconfig
添加環境變量,使用自定義引擎
mac@mac Flutter.framework % md5 Flutter
MD5 (Flutter) = 417ded8d1d0c7999c680ac31a9aae3f3
- 2.
Generated.xcconfig
注釋環境變量+編譯,使用發布版本引擎
mac@mac Flutter.framework % md5 Flutter
MD5 (Flutter) = 15efda2506d5e9c6904ceb1837b26124
- 3.
Generated.xcconfig
添加環境變量,使用自定義引擎
mac@mac Flutter.framework % md5 Flutter
MD5 (Flutter) = 0e4c584880f59b3b35ec48d68f820c93
- 4.
Generated.xcconfig
注釋環境變量+編譯,使用發布版本引擎
mac@mac Flutter.framework % md5 Flutter
MD5 (Flutter) = 6735d5613997e710ed37b9a27aab8bfc
- 可以看出,每一次的
md5值是不一樣的
工程每次編譯在生成Flutter.framework都是不一樣的(無論是發布版本還是自定義版本)
工程在每次編譯生成Flutter.framework的時候還要加入內容的,因此多次是不一樣的
7.Xcode13不顯示Product目錄
- 打開項目
project.pbxproj
- 搜索
productRefGroup
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146E51CF9000F007C117D /* Products */;
- 將
productRefGroup
的值換成mainGroup
的(這里的我已經修改好了) - Command+s保存后退出,就會發現工程中的Product目錄顯示出來了