国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

iOS問題記錄 - Xcode 14.3版本打包項目報錯

這篇具有很好參考價值的文章主要介紹了iOS問題記錄 - Xcode 14.3版本打包項目報錯。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


前言

前幾天升級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è)按鈕,展開詳情:

iOS問題記錄 - Xcode 14.3版本打包項目報錯

可以看到執(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è)置:

iOS問題記錄 - Xcode 14.3版本打包項目報錯

PODS_ROOT的定義在這:

iOS問題記錄 - Xcode 14.3版本打包項目報錯

驗證這個很簡單,只需要在這加上一行echo "${PODS_ROOT}"

iOS問題記錄 - Xcode 14.3版本打包項目報錯

重新執(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)境變量:

iOS問題記錄 - Xcode 14.3版本打包項目報錯

重新執(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á)的前往文件夾功能,找到絕對路徑所指向的位置:

iOS問題記錄 - Xcode 14.3版本打包項目報錯

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)了不同于前面的解決辦法:

  1. 切換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版本,那直接用不就好了。

  1. 利用Hook修改Pods-app-frameworks.sh文件內(nèi)容

前面的解決方法是在生成文件的時候加上-f參數(shù),而現(xiàn)在這個方法是在已經(jīng)生成的文件上修改。

iOS問題記錄 - Xcode 14.3版本打包項目報錯

這想法很好,不過直接拿來用會有問題。一是替換內(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或更高版本的方式解決該問題。

  1. 升級CocoaPods版本

個人比較推薦的方法,但是可能暫時還無法使用。問題將在1.12.1版本修復(fù),如果你遇到這個問題時,CocoaPods版本已經(jīng)發(fā)布到1.12.1或更高版本,推薦通過升級到最新版本解決該問題。

  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。

  1. 修改embed_frameworks_script.rb文件

文件位于CocoaPods包下的lib/cocoapods/generator/embed_frameworks_script.rb路徑,將文件中的source="$(readlink "${source}")"替換為source="$(readlink -f "${source}")",重新執(zhí)行pod install命令解決問題。

  1. 使用Xcode 14.2版本

既然都升級了,個人不是很推薦退回低版本,如果確實有需要,Xcode歷史版本官方下載(需要登錄)。

最后

如果這篇文章對你有所幫助,請不要吝嗇你的點贊??加星??,謝謝~文章來源地址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)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包