无法访问Swift包xcassets

ehxuflar  于 2023-02-18  发布在  Swift
关注(0)|答案(1)|浏览(124)

我尝试使用Swift Package(src)中xcassets文件夹中的颜色集。它似乎不起作用。我通过编写一个简单的视图尝试使用该颜色来测试这一点:

Text("Hello")
  .foregroundColor(Color("brandPrimary")

我从这段代码中得到了一个空视图;文本找不到颜色。
我在网络上做了大量的研究--回顾了一些WWDC视频,比如Swift packages: Resources and localization,他们似乎建议xcassets文件夹自动包含为资源。
我试着在package manifest中添加process("Resources/Colors.xcassets"),但也无济于事。

vxbzzdmp

vxbzzdmp1#

the Color documentation开始:
init(_ name: String, bundle: Bundle? = nil)
...

一米二米一x

要在其中搜索颜色资源的捆绑包。如果您未指定捆绑包,则初始化程序默认情况下会在应用的主捆绑包中查找。
GoodPackage库的资源不是应用的主包,因此您需要告诉Color初始化器要搜索哪个包。
Swift包管理器的构建过程会自动为每个包含资产的目标/模块创建一个Bundle。在模块中,你可以使用表达式Bundle.module访问生成的Bundle。SwiftPM实际上会将Swift代码写入DerivedData中名为resource_bundle_accessor.swift的文件中,以使其正常工作。生成的源代码如下所示:

import class Foundation.Bundle
import class Foundation.ProcessInfo
import struct Foundation.URL

private class BundleFinder {}

extension Foundation.Bundle {
    /// Returns the resource bundle associated with the current Swift module.
    static let module: Bundle = {
        let bundleName = "YourPackageName_YourTargetName"

        let overrides: [URL]
        #if DEBUG
        if let override = ProcessInfo.processInfo.environment["PACKAGE_RESOURCE_BUNDLE_URL"] {
            overrides = [URL(fileURLWithPath: override)]
        } else {
            overrides = []
        }
        #else
        overrides = []
        #endif

        let candidates = overrides + [
            // Bundle should be present here when the package is linked into an App.
            Bundle.main.resourceURL,

            // Bundle should be present here when the package is linked into a framework.
            Bundle(for: BundleFinder.self).resourceURL,

            // For command-line tools.
            Bundle.main.bundleURL,
        ]

        for candidate in candidates {
            let bundlePath = candidate?.appendingPathComponent(bundleName + ".bundle")
            if let bundle = bundlePath.flatMap(Bundle.init(url:)) {
                return bundle
            }
        }
        fatalError("unable to find bundle named YourPackageName_YourTargetName")
    }()
}

如您所见,static let module属性具有(默认)内部访问权限,因此您只能从该模块内的源代码使用它,默认情况下,无法从模块外部访问模块的Bundle
一种解决方案是为GoodPackage模块中的模块Bundle添加一个公共访问器。例如,将以下内容添加到GoodPackage模块中的源文件:

import Foundation

extension Bundle {
    public var GoodPackage: Bundle { Bundle.module }
}

然后,在您的应用中:

import GoodPackage

...

    Text("Hello")
        .foregroundColor(Color("brandPrimary", bundle: .GoodPackage))

相关问题