前言
前幾天升級Xcode到14.3版本,運行項目報錯,于是寫了iOS問題記錄 - Xcode 14.3版本運行項目報錯這篇文章。沒想到除了運行項目有問題,打包項目也有問題。
開發(fā)環(huán)境
- macOS: 13.3
- Xcode: 14.3
- CocoaPods: 1.12.0
問題描述
[Xcode菜單欄] -> [Product] -> [Archive],進(jìn)行打包操作。執(zhí)行到Run custom shell script '[CP] Embed Pods Frameworks'
時報錯,報錯相關(guān)日志如下:
Symlinked...
rsync --delete -av --filter P .*.?????? --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "../../../IntermediateBuildFilesPath/UninstalledProducts/iphoneos/xxx.framework" "/Users/xxx/Library/Developer/Xcode/DerivedData/app-dukdzczlzijlklamofogqicmtktj/Build/Intermediates.noindex/ArchiveIntermediates/app/InstallationBuildProductsLocation/Applications/app.app/Frameworks"
building file list ... rsync: link_stat "xxx/../../../IntermediateBuildFilesPath/UninstalledProducts/iphoneos/xxx.framework" failed: No such file or directory(2)
rsync error: some files could not be transferred (code 23) at /AppleInternal/Library/BuildRoots/97f6331a-ba75-11ed-a4bc-863efbbaf80d/Library/Caches/com.apple.xbs/Sources/rsync/rsync/main.c(996) [sender=2.6.9]
Command PhaseScriptExecution failed with a nonzero exit code
問題分析
從報錯信息看,是因為文件或目錄找不到報錯。因為項目有改動,所以暫時不確定是不是Xcode 14.3版本的原因。找到一臺裝有14.2版本的電腦,拉取最新代碼后執(zhí)行打包操作,一切正常!那看來這鍋Xcode得背,接下來就是找到具體原因和解決辦法。
首先要確定這個錯誤是在執(zhí)行什么代碼的時候出現(xiàn)的,才能進(jìn)一步分析。
找到Run custom shell script '[CP] Embed Pods Frameworks'
的右側(cè)按鈕,展開詳情:
可以看到執(zhí)行的shell腳本路徑是:
/Users/xxx/Library/Developer/Xcode/DerivedData/app-dukdzczlzijlklamofogqicmtktj/Build/Intermediates.noindex/ArchiveIntermediates/app/IntermediateBuildFilesPath/app.build/Release-iphoneos/app.build/Script-8D57CFCFEA49D25397FFD044.sh
shell腳本內(nèi)容:
#!/bin/sh
"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-frameworks.sh"
PODS_ROOT
的值是什么呢?你可能會想,直接在shell腳本中加上一行echo "${PODS_ROOT}"
不就知道了?不行的,每次執(zhí)行打包操作都會重新生成這個shell腳本,改動不會生效。其實會執(zhí)行這個自定義shell腳本,是因為在這有設(shè)置:
PODS_ROOT
的定義在這:
驗證這個很簡單,只需要在這加上一行echo "${PODS_ROOT}"
:
重新執(zhí)行打包操作,你會發(fā)現(xiàn)生成的shell腳本中也多了這一行:
#!/bin/sh
echo "${PODS_ROOT}"
"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-frameworks.sh"
同時在打包輸出日志中也正常打印出PODS_ROOT
的值。不知道有沒有人和我有一樣的疑問,生成的shell腳本中并沒有導(dǎo)入其他shell腳本或定義PODS_ROOT
,那么這個常量怎么來的?不難猜,PODS_ROOT
應(yīng)該來自環(huán)境變量。老辦法,加上env
命令打印一下環(huán)境變量:
重新執(zhí)行打包操作,會打印一大堆環(huán)境變量,這里就不一一列出??创蛴〕鰜淼沫h(huán)境變量,構(gòu)建設(shè)置基本都在里面(沒有一個個具體驗證)。大致可以得出結(jié)論,在構(gòu)建項目時,Xcode會把構(gòu)建設(shè)置設(shè)為臨時環(huán)境變量。
繼續(xù)往下分析,找到Pods-app-frameworks.sh
文件,根據(jù)報錯相關(guān)日志,報錯應(yīng)該發(fā)生在install_framework
函數(shù)中:
# Copies and strips a vendored framework
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
local source="${BUILT_PRODUCTS_DIR}/$1"
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
elif [ -r "$1" ]; then
local source="$1"
fi
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L "${source}" ]; then
echo "Symlinked..."
source="$(readlink "${source}")"
fi
if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
# Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
echo "Installing $f"
install_bcsymbolmap "$f" "$destination"
rm "$f"
done
rmdir "${source}/${BCSYMBOLMAP_DIR}"
fi
# Use filter instead of exclude so missing patterns don't throw errors.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
binary="${destination}/${basename}.framework/${basename}"
if ! [ -r "$binary" ]; then
binary="${destination}/${basename}"
elif [ -L "${binary}" ]; then
echo "Destination binary is symlinked..."
dirname="$(dirname "${binary}")"
binary="${dirname}/$(readlink "${binary}")"
fi
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
strip_invalid_archs "$binary"
fi
# Resign the code if required by the build settings to avoid unstable apps
code_sign_if_enabled "${destination}/$(basename "$1")"
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
for lib in $swift_runtime_libs; do
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
code_sign_if_enabled "${destination}/${lib}"
done
fi
}
執(zhí)行rsync --delete...
命令的時候,source
變量的路徑有問題。修改Pods-app-frameworks.sh
文件,增加一些日志打印用于追蹤source
變量的變化。經(jīng)測試,在執(zhí)行source="$(readlink "${source}")"
之前,source
變量中的路徑是絕對路徑:
/Users/xxx/Library/Developer/Xcode/DerivedData/app-dukdzczlzijlklamofogqicmtktj/Build/Intermediates.noindex/ArchiveIntermediates/app/BuildProductsPath/Release-iphoneos/SDWebImage/SDWebImage.framework
執(zhí)行后,變?yōu)橄鄬β窂剑?/p>
../../../IntermediateBuildFilesPath/UninstalledProducts/iphoneos/SDWebImage.framework
通過訪達(dá)的前往文件夾功能,找到絕對路徑所指向的位置:
SDWebImage.framework
是一個替身(軟鏈接/符號鏈接)。在SDWebImage
目錄路徑下執(zhí)行ls -l
查看實際指向的路徑:
lrwxr-xr-x 1 xxx staff 85 Apr 7 20:23 SDWebImage.framework -> ../../../IntermediateBuildFilesPath/UninstalledProducts/iphoneos/SDWebImage.framework
drwxr-xr-x 3 xxx staff 96 Apr 7 20:23 SDWebImage.framework.dSYM
看來readlink
命令的作用就是獲取軟連接所指向的實際路徑,那這路徑為什么報錯呢?有對比才能找到問題所在,同樣的項目用Xcode 14.2版本執(zhí)行打包操作,在SDWebImage
目錄路徑下執(zhí)行ls -l
查看實際指向的路徑:
lrwxr-xr-x 1 xxx staff 212 Apr 7 20:30 SDWebImage.framework -> /Users/xxx/Library/Developer/Xcode/DerivedData/app-dukdzczlzijlklamofogqicmtktj/Build/Intermediates.noindex/ArchiveIntermediates/app/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/SDWebImage.framework
drwxr-xr-x 3 xxx staff 96 Apr 7 20:30 SDWebImage.framework.dSYM
這么一對比,原因總算是找到了。Xcode 14.3版本構(gòu)建時將軟鏈接所指向的絕對路徑改為了相對路徑,導(dǎo)致找不到文件或目錄。
那么該怎么修復(fù)呢?可以先看看readlink
命令的文檔,使用man
(manual)命令查看:
man readlink
執(zhí)行命令后得到的文檔(省略部分):
NAME
stat, readlink – display file status
SYNOPSIS
stat [-FLnq] [-f format | -l | -r | -s | -x] [-t timefmt] [file ...]
readlink [-fn] [file ...]
DESCRIPTION
The stat utility displays information about the file pointed to by file. Read, write, or execute permissions of the named file are not required, but all directories listed in the pathname
leading to the file must be searchable. If no argument is given, stat displays information about the file descriptor for standard input.
When invoked as readlink, only the target of the symbolic link is printed. If the given argument is not a symbolic link and the -f option is not specified, readlink will print nothing and
exit with an error. If the -f option is specified, the output is canonicalized by following every symlink in every component of the given path recursively. readlink will resolve both
absolute and relative paths, and return the absolute pathname corresponding to file. In this case, the argument does not need to be a symbolic link.
The information displayed is obtained by calling lstat(2) with the given argument and evaluating the returned structure. The default format displays the st_dev, st_ino, st_mode, st_nlink,
st_uid, st_gid, st_rdev, st_size, st_atime, st_mtime, st_ctime, st_birthtime, st_blksize, st_blocks, and st_flags fields, in that order.
...
輸入q
退出文檔查看。readlink
命令參數(shù)不多,其中有個-f
參數(shù),這個參數(shù)的作用是遞歸找到第一個真實文件并返回該文件的絕對路徑(個人理解)。舉個例子??,假設(shè)A是真實文件,執(zhí)行ln -s A B
命令創(chuàng)建軟鏈接B,執(zhí)行ln -s B C
命令創(chuàng)建軟鏈接C,readlink C
命令獲取的是B,readlink -f C
命令獲取的是A的絕對路徑。
修改install_framework
函數(shù)中的readlink
命令,加上-f
參數(shù)。重新執(zhí)行打包操作,打包成功!分析到這,問題似乎已經(jīng)解決,可是當(dāng)我執(zhí)行完pod install
命令后,Pods-app-frameworks.sh
的文件內(nèi)容又恢復(fù)原狀了。這么看來,每次執(zhí)行pod install
命令都會重新生成Pods-app-frameworks.sh
文件,那如果能找到生成文件的代碼,在源頭修改不就能解決嗎?
不得不說macOS的可視化搜索真的不好用,電腦上的隱藏文件已經(jīng)設(shè)置為顯示,以install_framework
為關(guān)鍵詞搜索,搜不到有用的信息。沒辦法,只好用grep
命令來搜索:
grep -R install_framework ~
-R
表示遞歸搜索指定目錄(~
)下的全部文件,這里對用戶目錄進(jìn)行搜索,如果你已經(jīng)確定CocoaPods包所在目錄,則可以指定更詳細(xì)的目錄路徑加快搜索。搜索后,找到關(guān)鍵的文件路徑:
/Users/xxx/.rvm/gems/ruby-3.0.0/gems/cocoapods-1.12.0/lib/cocoapods/generator/embed_frameworks_script.rb
embed_frameworks_script.rb
文件內(nèi)容:
require 'cocoapods/xcode'
module Pod
module Generator
class EmbedFrameworksScript
# @return [Hash{String => Array<FrameworkPaths>}] Multiple lists of frameworks per
# configuration.
#
attr_reader :frameworks_by_config
# @return [Hash{String => Array<XCFrameworkPaths>}] Multiple lists of frameworks per
# configuration.
#
attr_reader :xcframeworks_by_config
# @param [Hash{String => Array<FrameworkPaths>] frameworks_by_config
# @see #frameworks_by_config
#
# @param [Hash{String => Array<XCFramework>] xcframeworks_by_config
# @see #xcframeworks_by_config
#
def initialize(frameworks_by_config, xcframeworks_by_config)
@frameworks_by_config = frameworks_by_config
@xcframeworks_by_config = xcframeworks_by_config
end
# Saves the resource script to the given pathname.
#
# @param [Pathname] pathname
# The path where the embed frameworks script should be saved.
#
# @return [void]
#
def save_as(pathname)
pathname.open('w') do |file|
file.puts(script)
end
File.chmod(0755, pathname.to_s)
end
# @return [String] The contents of the embed frameworks script.
#
def generate
script
end
private
# @!group Private Helpers
# @return [String] The contents of the embed frameworks script.
#
def script
script = <<-SH.strip_heredoc
#{Pod::Generator::ScriptPhaseConstants::DEFAULT_SCRIPT_PHASE_HEADER}
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
# frameworks to, so exit 0 (signalling the script phase was successful).
exit 0
fi
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
BCSYMBOLMAP_DIR="BCSymbolMaps"
#{Pod::Generator::ScriptPhaseConstants::RSYNC_PROTECT_TMP_FILES}
# Copies and strips a vendored framework
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
local source="${BUILT_PRODUCTS_DIR}/$1"
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
elif [ -r "$1" ]; then
local source="$1"
fi
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L "${source}" ]; then
echo "Symlinked..."
source="$(readlink "${source}")"
fi
if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
# Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
echo "Installing $f"
install_bcsymbolmap "$f" "$destination"
rm "$f"
done
rmdir "${source}/${BCSYMBOLMAP_DIR}"
fi
# Use filter instead of exclude so missing patterns don't throw errors.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \\"- CVS/\\" --filter \\"- .svn/\\" --filter \\"- .git/\\" --filter \\"- .hg/\\" --filter \\"- Headers\\" --filter \\"- PrivateHeaders\\" --filter \\"- Modules\\" \\"${source}\\" \\"${destination}\\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
binary="${destination}/${basename}.framework/${basename}"
if ! [ -r "$binary" ]; then
binary="${destination}/${basename}"
elif [ -L "${binary}" ]; then
echo "Destination binary is symlinked..."
dirname="$(dirname "${binary}")"
binary="${dirname}/$(readlink "${binary}")"
fi
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
strip_invalid_archs "$binary"
fi
# Resign the code if required by the build settings to avoid unstable apps
code_sign_if_enabled "${destination}/$(basename "$1")"
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\\\/\\(.+dylib\\).*/\\\\1/g | uniq -u)
for lib in $swift_runtime_libs; do
echo "rsync -auv \\"${SWIFT_STDLIB_PATH}/${lib}\\" \\"${destination}\\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
code_sign_if_enabled "${destination}/${lib}"
done
fi
}
#{Pod::Generator::ScriptPhaseConstants::INSTALL_DSYM_METHOD}
#{Pod::Generator::ScriptPhaseConstants::STRIP_INVALID_ARCHITECTURES_METHOD}
#{Pod::Generator::ScriptPhaseConstants::INSTALL_BCSYMBOLMAP_METHOD}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
# Use the current code_sign_identity
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
fi
echo "$code_sign_cmd"
eval "$code_sign_cmd"
fi
}
SH
contents_by_config = Hash.new do |hash, key|
hash[key] = ''
end
frameworks_by_config.each do |config, frameworks|
frameworks.each do |framework|
contents_by_config[config] << %( install_framework "#{framework.source_path}"\n)
end
end
xcframeworks_by_config.each do |config, xcframeworks|
xcframeworks.select { |xcf| xcf.build_type.dynamic_framework? }.each do |xcframework|
target_name = xcframework.target_name
name = xcframework.name
contents_by_config[config] << %( install_framework "#{Target::BuildSettings::XCFRAMEWORKS_BUILD_DIR_VARIABLE}/#{target_name}/#{name}.framework"\n)
end
end
script << "\n" unless contents_by_config.empty?
contents_by_config.keys.sort.each do |config|
contents = contents_by_config[config]
next if contents.empty?
script << %(if [[ "$CONFIGURATION" == "#{config}" ]]; then\n)
script << contents
script << "fi\n"
end
script << <<-SH.strip_heredoc
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi
SH
script
end
# @param [Xcode::FrameworkPaths] framework_path
# the framework path containing the dSYM
#
# @return [String, Nil] the name of the dSYM binary, if found
#
def dsym_binary_name(framework_path)
return nil if framework_path.dsym_path.nil?
if (path = Pathname.glob(framework_path.dsym_path.join('Contents/Resources/DWARF', '**/*')).first)
File.basename(path)
end
end
end
end
end
關(guān)鍵代碼是script
方法,方法內(nèi)部可以分為兩部分:
- 第一部分是
<<-SH.strip_heredoc...SH
,這是一個多行字符串(heredoc
),用于生成一些比較固定的內(nèi)容。在Ruby語法中,多行字符串一般這樣表示<<XXX...XXX
(XXX可以自定義,前后保持一致),加-
是為了字符串內(nèi)能縮進(jìn),strip_heredoc
方法用于刪除多余的縮進(jìn) - 第二部分從
contents_by_config = Hash.new do |hash, key|
到方法結(jié)束,這部分代碼會根據(jù)項目依賴的Pod庫生成類似這樣的內(nèi)容:
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi
以上只是簡單了解一下Pods-app-frameworks.sh
文件內(nèi)容是怎么生成的,如果你對這感興趣,可以嘗試自己調(diào)試CocoaPods源碼,調(diào)試環(huán)境的搭建可以參考CocoaPods - 源碼調(diào)試環(huán)境搭建。
將embed_frameworks_script.rb
文件中的source="$(readlink "${source}")"
改為source="$(readlink -f "${source}")"
,然后執(zhí)行pod install
命令重新生成Pods-app-frameworks.sh
文件,接著重新打包,一切正常!
不過,這也不是長久之計,關(guān)鍵還是要CocoaPods修復(fù)這個問題。已經(jīng)有人提了issue,連PR都有了,只不過還不知道啥時候發(fā)新版本。逛issue的過程中,發(fā)現(xiàn)了不同于前面的解決辦法:
- 切換
Command Line Tools
版本
Xcode 14.2版本有7.15GB,重新下載有點費時間,所以先看看只下載Command Line Tools for Xcode 14.2(671MB)行不行,安裝完成后發(fā)現(xiàn)不行,還是得下載Xcode 14.2版本。在Xcode 14.3版本中設(shè)置Command Line Tools
版本為14.2,嘗試打包還是報錯??磥磉@方法不太行,而且如果都安裝有14.2版本,那直接用不就好了。
- 利用Hook修改
Pods-app-frameworks.sh
文件內(nèi)容
前面的解決方法是在生成文件的時候加上-f
參數(shù),而現(xiàn)在這個方法是在已經(jīng)生成的文件上修改。
這想法很好,不過直接拿來用會有問題。一是替換內(nèi)容的時候雙引號沒有轉(zhuǎn)義,二是存在多target
的時候會找不到文件。除了解決這兩個問題,再簡單優(yōu)化一下,不再需要手動設(shè)置項目名稱:
post_install do |installer|
installer.pods_project.targets.each do |target|
shell_script_path = "Pods/Target Support Files/#{target.name}/#{target.name}-frameworks.sh"
if File::exists?(shell_script_path)
shell_script_input_lines = File.readlines(shell_script_path)
shell_script_output_lines = shell_script_input_lines.map { |line| line.sub("source=\"$(readlink \"${source}\")\"", "source=\"$(readlink -f \"${source}\")\"") }
File.open(shell_script_path, 'w') do |f|
shell_script_output_lines.each do |line|
f.write line
end
end
end
end
end
解決方案
如果沒有看前面的問題分析,建議先看一下。解決問題的方法有很多,以下羅列一些,供大家隨意選擇。
2023/04/10更新:如果你的項目是Flutter項目,除了以下方法,還可以通過升級Flutter到3.7.10或更高版本的方式解決該問題。
- 升級CocoaPods版本
個人比較推薦的方法,但是可能暫時還無法使用。問題將在1.12.1版本修復(fù),如果你遇到這個問題時,CocoaPods版本已經(jīng)發(fā)布到1.12.1或更高版本,推薦通過升級到最新版本解決該問題。
- 修改
Podfile
文件
加上這段代碼:
post_install do |installer|
installer.pods_project.targets.each do |target|
shell_script_path = "Pods/Target Support Files/#{target.name}/#{target.name}-frameworks.sh"
if File::exists?(shell_script_path)
shell_script_input_lines = File.readlines(shell_script_path)
shell_script_output_lines = shell_script_input_lines.map { |line| line.sub("source=\"$(readlink \"${source}\")\"", "source=\"$(readlink -f \"${source}\")\"") }
File.open(shell_script_path, 'w') do |f|
shell_script_output_lines.each do |line|
f.write line
end
end
end
end
end
重新執(zhí)行pod install
命令解決問題。你可能會遇到以下報錯:
undefined method `exists?' for File:Class
從Ruby 3.2.0版本開始,exists?
方法被移除了,解決方法是替換為exist?
方法。參考文檔:Ruby 3.2.0 Released。
- 修改
embed_frameworks_script.rb
文件
文件位于CocoaPods包下的lib/cocoapods/generator/embed_frameworks_script.rb
路徑,將文件中的source="$(readlink "${source}")"
替換為source="$(readlink -f "${source}")"
,重新執(zhí)行pod install
命令解決問題。
- 使用Xcode 14.2版本
既然都升級了,個人不是很推薦退回低版本,如果確實有需要,Xcode歷史版本官方下載(需要登錄)。文章來源:http://www.zghlxwxcb.cn/news/detail-415680.html
最后
如果這篇文章對你有所幫助,請不要吝嗇你的點贊??加星??,謝謝~文章來源地址http://www.zghlxwxcb.cn/news/detail-415680.html
到了這里,關(guān)于iOS問題記錄 - Xcode 14.3版本打包項目報錯的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!