【问题标题】:Can't assign xcassets to the main target on Xcode 11无法将 xcassets 分配给 Xcode 11 上的主要目标
【发布时间】:2020-01-04 12:27:21
【问题描述】:

在 Xcode 11 上,我的 .xcassets 在 Xcode 10 上不会导致任何问题,会导致编译失败并显示以下消息:

错误:多个命令产生“/Users/user/Library/Developer/Xcode/DerivedData/project-enjiypsgxtcdbnaripixgtnjlagx/Build/Products/Debug-iphonesimulator/project.app/Assets.car”:
1) 目标“项目”(项目“项目”)具有输入“/Users/user/sandbox/project/Resources/buttons.xcassets”的编译命令
2) 该命令依赖于 Target 'project' (project 'project') 中的命令:脚本阶段“[CP] Copy Pods Resources”

我能够编译项目的唯一方法是从目标中删除 .xcassets,明显的缺点是它们在构建中不可用。

PS:这发生在 2 个 ObjC 项目中。

【问题讨论】:

    标签: ios xcode xcasset


    【解决方案1】:

    如果有一些 pod 使用“resources”(不是“resources_bundle”)在 podspec 中链接自己的 xcasset,请检查您的依赖项。 这种方式已被弃用,因为它的输出文件名为“Assets.car”。它与您的项目 xcassets 的编译输出名称相同。

    【讨论】:

    • 这是正确的。添加到它,如果您不是 pod 的所有者,并且您无法更新它(如在我的一个项目中......),可以通过删除“Assets.car”来解决错误.../Pods/Target Support Files/Pods-Project/Pods-Project-resources-[Scheme]-output-files.xcfilelist 上的行。每次更新 pod 时都必须这样做......所以自动化它的脚本应该是一个好主意......
    【解决方案2】:

    answer above 只是部分正确:是的,这是因为 pod 阶段生成 Assets.car 作为输出文件,这与您的 xcassets 的输出名称一致strong> - 因此 Multiple commands produce... 错误:一个命令是脚本阶段 [CP] Copy Pods Resources 另一个 - 您自己项目的编译命令。

    但是从输出文件中删除 Assets.car 将导致构建系统无法看到脚本处理文件,因此它会跳过它(阅读this 了解更多详细信息)。所以我们可以做的是 add Assets.carinput 文件中 - 这将为脚本创建一个依赖项,告诉构建系统在执行脚本之前等待文件。

    注意:就像上面的解决方案一样,每次更新 pod 后都必须这样做,因为每次运行 pod installpod update 时都会生成 [CP] Copy Pods Resources

    【讨论】:

    • 不起作用,这是意料之中的,因为 Xcode 仍然抱怨两个构建阶段产生 Assets.car 并且 Xcode 对此也仍然正确。他们中的一个人也首先阅读了它并没有改变它背后的基本问题。
    • @Mecki 你是对的,这只是一种解决方法,而不是正确的解决方案。但是将 Assets.car 作为参数传递给其中一个构建阶段会为它们创建一个依赖项:现在 CP 阶段将等到该参数由项目编译命令创建,然后处理它而不是创建它自己的 - 这是我对我的回答中引用了讨论。
    【解决方案3】:

    Xcode->File->Workspace settings->Building System-> Legacy Build System

    example

    【讨论】:

    • 恕我直言,启用旧版配置而不是尝试找到适用于最新工具的解决方案只是一种说“我暂时忽略这个问题!”的方式。 :)
    • @JMiguel 我们都知道,像这样的临时修复会变成永久性修复。然后有一天,Apple 删除了旧系统,我们都注定要失败。
    • 这不是一个解决方案,就像跳过明天的问题一样。如果 Xcode 移除了遗留的构建系统,那么我们必须找到一个解决方案。
    【解决方案4】:

    为了确保所有构建步骤都以正确的顺序执行,并且尽可能多地并行执行,Xcode 需要知道每个构建步骤它依赖于哪些输入文件以及它将生成哪些输出文件。

    例如如果步骤 A 依赖的输入文件是步骤 B 的输出文件,那么步骤 B 肯定必须在步骤 A 之前运行。如果两个步骤都不需要另一步骤的输出文件,则它们都可以并行运行。

    虽然多个步骤肯定会依赖于同一个输入文件,但在这种情况下,多个步骤生成相同的输出文件是不可能的,最后运行的步骤将覆盖先运行的任何步骤的输出文件,这意味着生成的输出文件内容将是不可预测的,这是构建过程中的错误,应该会产生可预测的结果!

    在您的情况下,问题在于您的 Copy Resources 构建阶段包含一个(或多个).xcassets 捆绑包。 Xcode 不会只是复制这些包,而是将它们组合起来,转换和优化它们的内容,并创建一个名为 Assets.car 的文件,其中包含项目中所有资产目录的内容。

    然而,如果你集成了一个 Pod 并且这个 Pod 也有一个资产目录,完全相同的事情将会发生并且第二个 Assets.car 文件被创建,现在 Xcode 有一个问题:两个构建步骤都说他们创建了一个 @987654327 @ 文件。哪一个会赢?这两个文件中的哪一个最终会出现在最终应用程序中?那么依赖这个文件的其他步骤呢?他们必须在哪些构建步骤之后运行?这是 Xcode 无法解决的严重问题。

    目前有两种可能的解决方案:

    1. 使用框架。当您使用框架而不是静态库时,Pod 的资源最终不会在主应用程序的资源文件夹中,而是在构建框架的资源文件夹中。您需要做的就是将use_frameworks! 添加到您的 Podfile 中,无论是顶级还是仅针对特定目标。缺点是您的整体应用大小会增加一点,应用启动时间会增加一点。

    2. 让 Pod 作者修复 Pod。正如 Podspec 文档也强烈建议的那样,他/她应该使用 resources_bundle 而不是 resources。使用 resources 实际上还有其他缺点(资源文件未优化,不同 Pod 之间可能会出现名称冲突),而使用资源包是安全的,无论 Pod 嵌入为静态库还是动态框架。但请注意,仅更改 Podspec 是不够的,所有加载捆绑资源的代码都必须采用 load them from the correct bundle(在 Podspec 文件中使用 resources_bundle 时,名称将被称为,您还必须提供捆绑一个名称)。

    有一个关于这个问题的持续错误报告,你可以在这里找到它:
    https://github.com/CocoaPods/CocoaPods/issues/8122

    然而目前的问题是,除了上述两个之外,所有可能的解决方案基本上都是丑陋的 hack,而 Cocoapods 开发人员并不乐意实施丑陋的 hack。最好的解决方案,尽管看起来很困难,但可能根本不解决这个问题,而是停止在 Podspec 文件中支持resources,并使包含自有资源的 Pod 强制使用 resources_bundle

    【讨论】:

    • 感谢您的回答 Mercki!在我看来,您的帖子中有一个小错误:“缺点是您的整体应用程序大小会增加一点,应用程序启动时间会减少一点”。据我了解,不幸的是,动态链接的框架会增加应用程序的启动时间。我认为这值得指出,因为人们会认为选项 1 是一种灵丹妙药的解决方案 :)
    • @Romain 这正是我所说的。我说过当你使用框架时应用启动时间会减少一点。
    • 我是说它会增加它。 “使用框架!”将 pod 构建为动态框架 (blog.cocoapods.org/CocoaPods-0.36),动态框架会导致更长的启动时间。
    • @Romain 好的,现在我明白了。这只是写得不好。减少应用程序启动时间应该意味着“你的应用程序会变得更糟”,而减少不是表达它变得更糟的正确词,因为它也“缩短”这意味着相反。会解决的。
    • 好的,我看到了混乱?谢谢指正!!
    【解决方案5】:

    在您的库项目中,例如“LADetailPage”,打开 Targets 的“Build Phases”,创建一个名为“Copy Files”的预定义阶段,然后将您的 *.xcassets 拖到新阶段。

    那么库在构建时不会从*.xcassets文件生成Assets.car,而是cocoapods将*.xcassets复制到导入lib的主项目中,主项目将所有*.xcassets构建为一个Assets.car 文件。

    【讨论】:

    • @HarshalBhavsar 你用的是什么cocoapods,Xcode版本?
    • @maslovsa 实际上我们遇到了一个问题,现在应用图标丢失了,因为图像资源无法正常工作
    • @HarshalBhavsar 与 AppIcon + Crash with Images access(存储在 Assets.xcassets 中)同样的问题
    【解决方案6】:

    在您的 pod 文件顶部添加以下行,紧跟在 platform :ios 之后

    install! 'cocoapods', :disable_input_output_paths => true
    

    Reference

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-30
      相关资源
      最近更新 更多