Xcode 新构建系统 CocoaPods "Copy Pods Resources" 在输出文件中有 Assets.car 并与 "Copy Bundle Resources" 冲突

Xcode New Build System CocoaPods "Copy Pods Resources" has Assets.car in Output Files and conflict with "Copy Bundle Resources"

我们的 Xcode 项目正在使用新的构建系统和 Cocoapods 1.7.5。我们的项目(我们称它为 Y)实际上是一个开发 pod,但我们也编写了一些代码来创建应用程序演示(你知道,使构建更快,迭代更快)。这些演示代码(AppDelegate.swift、启动任务等)不包含在开发 pod 中。其余约 90% 的源代码和资源文件(例如 i18n 字符串和图像资源)被打包到开发 pod 中供另一个项目(我们称之为 X)使用。

在开发过程中,大部分更改发生在 Y 的开发单元部分,因此我们需要确保在 X 进行更改时包含每个更改部分 pod install

最近我们遇到了一个问题:

error: Multiple commands produce '/Users/x/Library/Developer/Xcode/DerivedData/Y-cawteybtitmeiafweribgqzkuhnr/Build/Products/Debug-iphoneos/Y.app/Assets.car':
1) Target 'Y' (project 'Y') has compile command with input '/Users/name/DEV/workspace/Y/SupportFiles/Assets.xcassets'
2) That command depends on command in Target 'Y' (project 'Y'): script phase “[CP] Copy Pods Resources”

在 Google 上搜索 multiple commands produce assets.car 几个小时后,我们终于看到了一个合理的 explanation

*.xcassets of Copy Bundle Resources --> Assets.car

*.xcassets of [CP] Copy Pods Resource --> other Assets.car

The first one covers second in the New Build System,That's the reason.

当我们从 [CP] Copy Pods Resource 的输出文件中手动删除 ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Assets.car 时,错误消失,一切正常。但是,每当我们 git checkout 到另一个分支,或 pod install,或 pod update 时,${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Assets.car 很有可能再次出现在 [=20 的输出文件中=].我们需要一次又一次地手动删除它,这既乏味又令人沮丧。

然后我们开始质疑:这一切的幕后黑手是谁?谁负责将 ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Assets.car 添加到 [CP] Copy Pods Resource 的输出文件中?我们将视线集中在 Y.podspec 上,发现了这些行:

  s.resource_bundles = {
    'Y' => ['Resources/*'], # assets, lottie etc.
    'YAuto' => ['auto_resources/*'] # i18n strings etc.
  }

我们认为我们使用的 resource_bundles 有误,所以我们再次在 Google 上进行了查找。令人惊讶的是,official documentation 推荐使用 resource_bundles 而不是 resources。此外,我们找不到 resource_bundles 方面的任何不当用法,让我们别无选择。

有人可以帮忙吗?我在想也许我们可以在 Podfilepost_install 脚本中修补 Y.xcworkspace,但我不知道怎么做。

我通过在 Podfile 中编写 post_install 脚本解决了这个问题,它会自动删除这些 Assets.car

post_install do |installer|
    project_path = 'Y.xcodeproj'
    project = Xcodeproj::Project.open(project_path)
    project.targets.each do |target|
        build_phase = target.build_phases.find { |bp| bp.display_name == '[CP] Copy Pods Resources' }
        assets_path = '${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Assets.car'
        if build_phase.present? && build_phase.output_paths.include?(assets_path) == true
            build_phase.output_paths.delete(assets_path)
        end
    end
    project.save(project_path)
end

好像是 CocoaPods 的一个 bug,到现在还没修复。

快一个月了,这里有更新。原来这个问题是误用了Y的另一个开发pod造成的。我们忘记在那个 dev pod 的 Podspec 中使用 resource_bundles,这导致那个 dev pod 的资源没有被打包到一个 .bundle 文件中,然后是 [CP] Copy Pods Resources 显式将 xcassets 添加到输入文件中,与 Copy Bundle Resources.

中的另一个发生冲突

这个问题有很多方面;除了 iOS 应用程序之外,有些人喜欢上面描述的问题,有时还有共享扩展程序或观看应用程序。在所有情况下,这是由于在那些创建重复 Assets.car 文件的目标的 [CP] Copy Pods Resources 中存在多个 Assets.car 输出造成的。编译器显然不知道如何处理,所以我们不应该允许 CocoaPods 生成多个同名的输出文件。

根据 the CocoaPods issue 推荐的解决方案是将其放入您的 Podfile:

# Default platform for most targets
platform :ios, '11.0'

# Workaround duplicate Assets.car issue https://github.com/CocoaPods/CocoaPods/issues/8122
# This impacts the new Xcode build system
install! 'cocoapods', :disable_input_output_paths => true

Xcode 12 还修复了伴随的问题,该问题会导致在使用具有此解决方法的新构建系统时构建性能问题。自 Xcode 12.

起正式弃用旧构建系统