Flutter - 危!3.24版本苹果审核被拒!
# 一、概述
最近准备使用 Flutter
的 3.24
版本打包上架 APP
,结果前天看到有人提了一个 issue
: https://github.com/flutter/flutter/issues/158423 (opens new window) ,说分别使用 3.24.3
和 3.24.4
提交苹果审核时,都惨遭被拒~
苹果反馈的信息如下:
Guideline 2.5.1 - Performance - Software Requirements
The app uses or references the following non-public or deprecated APIs:
Frameworks/Flutter.framework/Flutter
Symbols:
• _kCTFontPaletteAttribute
• _kCTFontPaletteColorsAttribute
The use of non-public or deprecated APIs is not permitted, as they can lead to a poor user experience should these APIs change and are otherwise not supported on Apple platforms.
可以看到,是说 Flutter
使用了未公开的 API
,并且他使用 strings
命令也验证了这一点。
3.24.x
strings Runner.app/Frameworks/Flutter.framework/Flutter | grep kCT
SkCTMShader
kCTFontVariationAxisHiddenKey
kCTFontPaletteAttribute
kCTFontPaletteColorsAttribute
3.22.3
strings Runner.app/Frameworks/Flutter.framework/Flutter | grep kCT
SkCTMShader
kCTFontVariationAxisHiddenKey
我先在 Flutter
引擎源码中搜索,结果压根就搜索不到,随后打开了前几日编译好的引擎调试项目,结果一搜一个准,在 third_party
依赖下的 Skia
代码中,很快就定位到了引入未公开 API
的相关提交记录 https://skia-review.googlesource.com/c/skia/+/867836 (opens new window) 。
我一看完就啪的一声敲起来了,很快啊!上来就是一个 Revert
https://skia-review.googlesource.com/c/skia/+/918416 (opens new window) 。
目前此次受影响的 Flutter
版本范围暂时是 3.24.0
~ 3.24.4
,得等待新版本的发布才可以解决。建议还没用上 3.24
的小伙伴先不要升级,那如果已经是 3.24
或者是一定要用 3.24.4
及以下版本的小伙伴要怎么办呢?那就跟我一起来自编译引擎吧~
# 二、编译引擎
# 环境
注意:全程需要科学上网环境,请自行查找和配置
首先拉取最新的 depot_tools
,放到一个合适的位置,比如我放在 ~/development
目录下
cd ~/development
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
将 depot_tools
添加至环境变量,在你的终端配置文件里补充如下内容
终端配置文件因人而异,如:
~/.bash_profile
、~/.zshrc
、~/.zprofile
,请自行判断
export PATH = "$HOME/development/depot_tools":$PATH
然后 source ~/.zshrc
(这里请根据自身情况修改终端配置文件路径)
# 拉源码
找个合适的目录,创建 engine
目录并进入
mkdir engine
cd engine
开始拉取源码
fetch flutter
它会在当前目录下创建 .gclient
文件,写好配置,并执行 gclient sync
solutions = [
{
"custom_deps": {},
"deps_file": "DEPS",
"managed": False,
"name": "src/flutter",
"safesync_url": "",
"url": "https://github.com/flutter/engine.git",
},
]
如果在拉取代码的过程中遇到如下问题
remote: Enumerating objects: 835563, done.
remote: Counting objects: 100% (1612/1612), done.
remote: Compressing objects: 100% (1011/1011), done.
error: RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL (err 8)
error: 1481 bytes of body are still expected
fetch-pack: unexpected disconnect while reading sideband packet
fatal: early EOF
fatal: fetch-pack: invalid index-pack output
src/flutter (ERROR)
----------------------------------------
[0:00:00] Started.
别慌,执行下方命令让其接着拉,直至完成
gclient sync
拉取完成后,去查看我们使用的 Flutter
版本对应的引擎版本,这里以 3.24.4
为例,打开链接:https://github.com/flutter/flutter/blob/3.24.4/bin/internal/engine.version ,拿到 db49896cf25ceabc44096d5f088d86414e05a7aa
执行如下命令进行切换
cd src/flutter
git checkout db49896cf25ceabc44096d5f088d86414e05a7aa
执行完成会输出如下内容
Previous HEAD position was b0a4ca92c4 Add FlPointerManager to process pointer events from GTK in a form suitable for Flutter. (#56443)
HEAD is now at db49896cf2 [CP-stable]Add xcprivacy privacy manifest to macOS framework (#55366)
post-checkout: The engine source tree has been updated.
You may need to run "gclient sync -D"
按照提示执行
gclient sync -D
# 调整源码
按路径 engine/src/flutter/third_party/skia/src/ports/SkTypeface_mac_ct.cpp
打开文件,按下方内容进行修改(红:删除,绿:新增)
static CFStringRef getCTFontPaletteAttribute() {
- static CFStringRef* kCTFontPaletteAttributePtr =
- static_cast<CFStringRef*>(dlsym(RTLD_DEFAULT, "kCTFontPaletteAttribute"));
- return *kCTFontPaletteAttributePtr;
+ return nullptr;
+ //static CFStringRef* kCTFontPaletteAttributePtr =
+ // static_cast<CFStringRef*>(dlsym(RTLD_DEFAULT, "kCTFontPaletteAttribute"));
+ //return *kCTFontPaletteAttributePtr;
}
static CFStringRef getCTFontPaletteColorsAttribute() {
- static CFStringRef* kCTFontPaletteColorsAttributePtr =
- static_cast<CFStringRef*>(dlsym(RTLD_DEFAULT, "kCTFontPaletteColorsAttribute"));
- return *kCTFontPaletteColorsAttributePtr;
+ return nullptr;
+ //static CFStringRef* kCTFontPaletteColorsAttributePtr =
+ // static_cast<CFStringRef*>(dlsym(RTLD_DEFAULT, "kCTFontPaletteColorsAttribute"));
+ //return *kCTFontPaletteColorsAttributePtr;
}
...
static bool apply_palette(CFMutableDictionaryRef attributes,
const SkFontArguments::Palette& palette) {
bool changedAttributes = false;
- if (palette.index != 0 || palette.overrideCount) {
+ if ((palette.index != 0 || palette.overrideCount) && getCTFontPaletteAttribute()) {
SkUniqueCFRef<CFNumberRef> paletteIndex(
CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &palette.index));
CFDictionarySetValue(attributes, getCTFontPaletteAttribute(), paletteIndex.get());
changedAttributes = true;
}
- if (palette.overrideCount) {
+ if (palette.overrideCount && getCTFontPaletteColorsAttribute()) {
SkUniqueCFRef<CFMutableDictionaryRef> overrides(
...
相应修改来自: https://skia-review.googlesource.com/c/skia/+/918518 (opens new window)
# 编译
来到 engine/src
目录,使用 gn
编译生成 ninja
构建文件
./flutter/tools/gn --runtime-mode release --mac-cpu arm64
./flutter/tools/gn --ios --runtime-mode release
使用 ninja
编译引擎的最终产物
ninja -C out/host_release_arm64
ninja -C out/ios_release
如果你当前是 MacOS 15
的 Sequoia
系统,在执行 ninja -C out/host_release_arm64
时会遇到如下错误
COPY '/System/Library/Fonts/A...arty/txt/assets/Apple Color Emoji.ttc'
FAILED: gen/flutter/third_party/txt/assets/Apple Color Emoji.ttc
ln -f '/System/Library/Fonts/Apple Color Emoji.ttc' 'gen/flutter/third_party/txt/assets/Apple Color Emoji.ttc' 2>/dev/null || (rm -rf 'gen/flutter/third_party/txt/assets/Apple Color Emoji.ttc' && cp -af '/System/Library/Fonts/Apple Color Emoji.ttc' 'gen/flutter/third_party/txt/assets/Apple Color Emoji.ttc')
cp: chflags: gen/flutter/third_party/txt/assets/Apple Color Emoji.ttc: Operation not permitted
[18/4139] SOLINK libvk_swiftshader.dylib libvk_swiftshader.dylib.TOC
ninja: build stopped: subcommand failed.
别急,打开 engine/src/build/toolchain/mac/BUILD.gn
,做如下修改,修改完再执行 gn
和 ninja
tool("copy") {
- command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} && cp -af {{source}} {{output}})"
+ command = "ln -f {{source}} {{output}} 2>/dev/null || (rsync -a --delete {{source}} {{output}})"
description = "COPY {{source}} {{output}}"
}
相应的 issue
: #152978 (opens new window)
好了,静静等待编译完成。
请注意,这将是个十分漫长且全程 CPU
占用率为 100%
的过程~
建议使用一台空闲的 Mac
电脑去做这个事!否则你将啥活也干不了~
# 验证
进入 engine/src/out/ios_release
strings Flutter.framework/Flutter | grep kCT
SkCTMShader
kCTFontVariationAxisHiddenKey
可以看到,没有 kCTFontPaletteAttribute
和 kCTFontPaletteColorsAttribute
。
# 使用本地引擎
执行如下命令对项目进行编译
flutter build ipa \
--local-engine-src-path=/Users/lxf/engine/src \
--local-engine=ios_release \
--local-engine-host=host_release_arm64
如果你有使用 realm
的话,可能会遇到如下错误
Installing realm (1.0.3)
[!] /bin/bash -c
set -e
source "/Users/lxf/app/ios/Flutter/flutter_export_environment.sh" && cd "$FLUTTER_APPLICATION_PATH" && "$FLUTTER_ROOT/bin/flutter" pub run realm install --target-os-type ios --flavor flutter
You must specify --local-engine or --local-web-sdk if you are using a locally built engine or web sdk.
你需要对该文件
/Users/lxf/app/ios/.symlinks/plugins/realm/ios/realm.podspec
进行修改,在 \"$FLUTTER_ROOT/bin/flutter\"
和 pub
中间加上引擎相关参数。如下所示
s.prepare_command = "source \"#{project_dir}/Flutter/flutter_export_environment.sh\" && cd \"$FLUTTER_APPLICATION_PATH\" && \"$FLUTTER_ROOT/bin/flutter\" --local-engine-src-path /Users/lxf/engine/src --local-engine ios_release --local-engine-host host_release_arm64 pub run realm install --target-os-type ios --flavor flutter"
:script => 'source "$PROJECT_DIR/../Flutter/flutter_export_environment.sh" && cd "$FLUTTER_APPLICATION_PATH" && "$FLUTTER_ROOT/bin/flutter" --local-engine-src-path /Users/lxf/engine/src --local-engine ios_release --local-engine-host host_release_arm64 pub run realm install --target-os-type ios --flavor flutter',
如果你只是想对项目进行配置,则将 ipa
改为 ios
,并加上 --config-only
参数即可。
flutter build ios \
--local-engine-src-path=/Users/lxf/engine/src \
--local-engine=ios_release \
--local-engine-host=host_release_arm64 \
--config-only
以前使用本地引擎只需要 --local-engine
参数,现在要求结合 --local-engine-host
一块使用,这里附上相关 issue
:https://github.com/flutter/flutter/issues/132245 (opens new window) ,想了解的可以点开看看
# 三、最后
过程不难,麻烦的是拉源码和编译真的好慢,而且空间占用还大~
好了,本篇到此结束,感谢大家的支持,我们下次再见! 👋
- 01
- Flutter - 子部件任意位置观察滚动数据11-24
- 02
- Flutter - 轻松搞定炫酷视差(Parallax)效果09-21
- 03
- Flutter - 轻松实现PageView卡片偏移效果09-08