应用程序的 xib/storyboard 如何渲染资产目录(这是一个 swift 包资源)中的图像?

Vap*_*olf 6 xcode asset-catalog swift swift-package-manager xcode-build-settings

关于

我们的资产目录已从应用程序目标移至 swift 包资源。此后,应用程序现有的故事板/xib 无法再渲染这些资产,除非通过Copy Bundle Resources阶段复制资产目录(这意味着编译的应用程序中有 2 个副本)。有没有更好的办法?

考虑资产目录迁移之前和之后的工作区。

迁移 Assets.xcasset 之前

- FooApp/
  - FooApp/
    - Resources/
      - Assets.xcasset // #1.1 Standard asset catalog in app target
      - Assets.swift // internal scope access to images in Assets.xcasset (swiftgen)
    - ViewController/
      - MyViewController.swift
      - MyViewController.storyboard // #1.2 Contains a view which renders "imageA" from Assets.xcasset
    - View/
      - MyView.xib // #1.3 xib renders "imageB" from Assets.xcasset
      - MyUIKitView.swift // Programmatically renders "imageC" from Assets.xcasset
      - MySwiftUIView.swift // Programmatically renders "imageD" from Assets.xcasset
Run Code Online (Sandbox Code Playgroud)

应用程序按预期工作。此处设置的典型资产目录。图像的消费方式有多种:

  • 以编程方式(UIKit 和 SwiftUI)
  • 视觉上(xib 和故事板)

之后(将 Assets.xcassets 移至 MyPackage)

- FooApp/
  - FooApp/
    - Resources/
      - // #2.1 Assets.xcasset was relocated to MyPackage
    - ViewController/
      - MyViewController.swift
      - MyViewController.storyboard // #2.2 Contains a view which renders "imageA" from Assets.xcasset
    - View/
      - MyView.xib // Contains a subview which renders "imageB" from Assets.xcasset
      - MyUIKitView.swift // Programmatically renders "imageC" from Assets.xcasset
      - MySwiftUIView.swift // Programmatically renders "imageD" from Assets.xcasset
- MyPackage/
  - Package.swift // calls `.process("Resources/Assets.xcassets")`
  - Sources/
    - MyPackage/
      - Resources/
        - Assets.xcassets // Same asset catalog from #Before
        - Assets.swift // public scope access to images in Assets.xcasset (swiftgen)
Run Code Online (Sandbox Code Playgroud)
  • 创建一个新的 swift 包(MyPackage)
  • 移动Assets.xcassetsAssets.swiftMyPackage
  • 在 中MyPackage/Package.swift,调用.process("Resources/Assets.xcassets")
  • 将我们的程序化图像访问器更改为public范围

这是我们开始遇到问题的地方。

问题

  • [通过]MyPackage和应用程序都编译时没有警告/错误。链接和启动都很好
  • [通过] 在运行时,对图像的任何编程引用都会按预期呈现。
  • [失败] 在运行时,任何呈现的 xib/storyboard 文件都无法渲染图像。
    • [注意] 如果我在 Xcode 中检查 xib/storyboard,图像就会呈现。
    • [注意] 如果我单击图像(就像我要选择另一个图像一样),弹出列表会正确呈现Assets.xcassets.

因此,Xcode 对图像有足够的了解,可以渲染它们,并在没有警告或错误的情况下进行编译,但图像在运行时丢失。

解决方案(有副作用)

经过一番研究后,我找到了一个可行的解决方案(但我对此不满意):

在应用程序的构建阶段设置中,我添加了一个复制的项目MyPackage/Sources/MyPackage/Resources/Assets.xcassets

再次编译/运行后,图像可以正确渲染故事板/xib。不错,但有一些不良的副作用:

  1. 编译/链接的二进制文件包含两个Assets.xcassets. 一进MyPackage一出复制到App Bundle中。
  2. 在 Xcode 中,Assets.xcassets在项目中出现两次。一个在MyPackage应用程序源的根目录中,另一个在应用程序源的根目录中。在不中断复制阶段的情况下无法移动或隐藏它。它们至少是符号链接的,因此编辑就是编辑另一个。

备择方案?

是时候寻求帮助了。我认为这不是最好的/预期的方式。我已经用尽我的谷歌了。在 Apple 文档中找不到具体信息。

我想象有一种更定制的方法来执行复制步骤(可能不包括 Package.swift 中的资产目录)?或者可能是在“构建规则”选项卡中编译资产目录的方法?

或者我的做法正确吗?