如何在Swift Package Manager库中包含资源/资源?

dan*_*emm 31 swift swift-package-manager

我想使用Apple的Swift Package Manager运送我的库.但是,我的lib包含一个.bundle文件,其中包含多个以不同语言翻译的字符串.使用cocoapods,我可以使用spec.resource包含它.但是在SwiftPM中,我不能这样做.有解决方案吗

Dan*_*bar 32

包管理器还没有关于如何将资源与目标捆绑在一起的任何定义.我们意识到需要这样做,但尚未提出具体建议.我提交了https://bugs.swift.org/browse/SR-2866以确保我们有一个跟踪此错误的错误.

  • 更新:随着 Swift 5.3 的发布,它肯定会在 2020 年 5 月至 9 月期间发布。 https://forums.swift.org/t/se-0271-package-manager-resources/30730/74 (4认同)

Bil*_*fas 14

使用 Swift 5.3 终于可以添加本地化资源了

包初始值设定项现在有一个defaultLocalization可用于本地化资源的参数。

public init(
    name: String,
    defaultLocalization: LocalizationTag = nil, // New defaultLocalization parameter.
    pkgConfig: String? = nil,
    providers: [SystemPackageProvider]? = nil,
    products: [Product] = [],
    dependencies: [Dependency] = [],
    targets: [Target] = [],
    swiftLanguageVersions: [Int]? = nil,
    cLanguageStandard: CLanguageStandard? = nil,
    cxxLanguageStandard: CXXLanguageStandard? = nil
)
Run Code Online (Sandbox Code Playgroud)

假设您有一个Icon.png想要为说英语和德语的人本地化的内容。

图像应包含在Resources/en.lproj/Icon.png& 中Resources/de.lproj/Icon.png

在你可以像这样在你的包中引用它们之后:

let package = Package(
    name: "BestPackage",
    defaultLocalization: "en",
    targets: [
        .target(name: "BestTarget", resources: [
            .process("Resources/Icon.png"),
        ])
    ]
)
Run Code Online (Sandbox Code Playgroud)

请注意LocalizationTagIETF Language Tag的包装器。

以下提案概述的学分和输入,请检查以获取更多详细信息。


Wen*_*iga 6

从 Swift 5.3 开始,借助SE-0271resources ,您可以通过添加声明来在 swift 包管理器上添加捆绑资源.target

例子:

.target(
   name: "HelloWorldProgram",
   dependencies: [], 
   resources: [.process(Images), .process("README.md")]
)
Run Code Online (Sandbox Code Playgroud)

如果你想了解更多,我在medium上写了一篇文章,讨论这个话题


The*_*Art 5

由于尚不支持框架捆绑包,因此为捆绑包资产提供 SPM 目标的唯一方法是通过捆绑包。如果您在框架中实现代码来搜索主项目中的特定包(支持资源包),则可以从该包加载资源。

例子:

访问捆绑资源:

extension Bundle {
    static func myResourceBundle() throws -> Bundle {
        let bundles = Bundle.allBundles
        let bundlePaths = bundles.compactMap { $0.resourceURL?.appendingPathComponent("MyAssetBundle", isDirectory: false).appendingPathExtension("bundle") }
        
        guard let bundle = bundlePaths.compactMap({ Bundle(url: $0) }).first else {
            throw NSError(domain: "com.myframework", code: 404, userInfo: [NSLocalizedDescriptionKey: "Missing resource bundle"])
        }
        return bundle
    }
}
Run Code Online (Sandbox Code Playgroud)

利用捆绑资源:

let bundle = try! Bundle.myResourceBundle()
return UIColor(named: "myColor", in: bundle, compatibleWith: nil)!
Run Code Online (Sandbox Code Playgroud)

您可以对所有资源文件应用相同的逻辑,包括但不限于故事板、xib、图像、颜色、数据 blob 以及各种扩展名的文件(json、txt 等)。

注意:有时这是有道理的,有时却没有道理。根据自己的项目自行决定使用。需要非常具体的场景来证明将 Storyboard/Xib 分离到捆绑资产中的合理性。