无法访问 Swift 包 xcassets

Kel*_*Lau 5 swift swift-package-manager swift-package

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

Text("Hello")
  .foregroundColor(Color("brandPrimary")
Run Code Online (Sandbox Code Playgroud)

我从这段代码中得到了一个空视图;文本找不到颜色。

我围绕网络进行了大量研究 - 回顾 WWDC 视频,例如Swift 包:资源和本地化,他们似乎建议该xcassets文件夹自动包含为资源。这对我不起作用。

我尝试process("Resources/Colors.xcassets")在我的包清单中添加,但这也没有帮助。

rob*_*off 5

文档Color

\n
\n

init(_ name: String, bundle: Bundle? = nil)

\n

\xe2\x80\xa6

\n

bundle

\n
\n

在其中搜索颜色资源的包。如果您不指定捆绑包,则初始化程序默认会在您的 app\xe2\x80\x99s 主捆绑包中查找。

\n
\n
\n

您的 GoodPackage 库的资源不是应用程序的主包,因此您需要告诉Color初始化程序要搜索哪个包。

\n

Swift 包管理器的构建过程会自动Bundle为包含资产的每个目标/模块创建一个。在模块内,您可以访问Bundle使用表达式生成的内容Bundle.moduleresource_bundle_accessor.swiftSwiftPM 实际上将 Swift 代码写入到DerivedData 中指定的文件中以实现此目的。生成的源代码如下所示:

\n
import class Foundation.Bundle\nimport class Foundation.ProcessInfo\nimport struct Foundation.URL\n\nprivate class BundleFinder {}\n\nextension Foundation.Bundle {\n    /// Returns the resource bundle associated with the current Swift module.\n    static let module: Bundle = {\n        let bundleName = "YourPackageName_YourTargetName"\n\n        let overrides: [URL]\n        #if DEBUG\n        if let override = ProcessInfo.processInfo.environment["PACKAGE_RESOURCE_BUNDLE_URL"] {\n            overrides = [URL(fileURLWithPath: override)]\n        } else {\n            overrides = []\n        }\n        #else\n        overrides = []\n        #endif\n\n        let candidates = overrides + [\n            // Bundle should be present here when the package is linked into an App.\n            Bundle.main.resourceURL,\n\n            // Bundle should be present here when the package is linked into a framework.\n            Bundle(for: BundleFinder.self).resourceURL,\n\n            // For command-line tools.\n            Bundle.main.bundleURL,\n        ]\n\n        for candidate in candidates {\n            let bundlePath = candidate?.appendingPathComponent(bundleName + ".bundle")\n            if let bundle = bundlePath.flatMap(Bundle.init(url:)) {\n                return bundle\n            }\n        }\n        fatalError("unable to find bundle named YourPackageName_YourTargetName")\n    }()\n}\n
Run Code Online (Sandbox Code Playgroud)\n

如您所见,该static let module属性具有(默认)内部访问权限,因此您只能从该模块内的源代码中使用它。默认情况下,无法Bundle从模块外部访问模块。

\n

Bundle一种解决方案是在 GoodPackage 模块中添加该模块的公共访问器。例如,将其添加到 GoodPackage 模块中的源文件中:

\n
import Foundation\n\nextension Bundle {\n    public var GoodPackage: Bundle { Bundle.module }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

然后,在您的应用程序中:

\n
import GoodPackage\n\n...\n\n    Text("Hello")\n        .foregroundColor(Color("brandPrimary", bundle: .GoodPackage))\n
Run Code Online (Sandbox Code Playgroud)\n