问题
I would like to ship my library using Apple's Swift Package Manager. However my lib includes a .bundle file with several strings translated in different languages. Using cocoapods, I can include it using spec.resource. But in SwiftPM, I cannot do it. Any solution?
回答1:
The package manager does not yet have any definition for how resources will be bundled with targets. We are aware of the need for this, but don't yet have a concrete proposal for it. I filed https://bugs.swift.org/browse/SR-2866 to ensure we have a bug tracking this.
回答2:
Due to framework bundles not being supported yet, the only way to provide bundle assets with an SPM target is through a Bundle. If you implement code in your framework to search for a particular bundle in your main project (supporting asset bundles), you can load resources from said bundle.
Example:
Access the bundled resources:
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
}
}
Utilize the Bundled resources:
let bundle = try! Bundle.myResourceBundle()
return UIColor(named: "myColor", in: bundle, compatibleWith: nil)!
You can apply the same logic for all resource files, including but not limited to storyboards, xibs, images, colors, data blobs, and files of various extensions (json, txt, etc).
Note: Sometimes this makes sense, sometimes it doesn't. Determine use to own project's discretion. It would take very specific scenarios to justify separating Storyboards/Xibs into bundled assets.
回答3:
You can also load individual resources dynamically.
Suppose your packages test need some mock JSON data. You'd place the mock JSON files in a Tests/JSONMocks
directory. Then in Package.swift
:
targets: [
.testTarget(
name: "MyTargetTests",
dependencies: ["MyTarget"],
path: "Tests"
),
]
And load them dynamically:
static func dataForJSONFileNamed(string: String) -> Data {
// find mock JSON files if using Swift Package Manager:
let currentDirectoryURL = URL(fileURLWithPath: FileManager.default.currentDirectoryPath)
let fileURL = currentDirectoryURL
.appendingPathComponent("Tests", isDirectory: true)
.appendingPathComponent("JSONMocks", isDirectory: true)
.appendingPathComponent(string)
.appendingPathExtension("json")
let jsonFileData = try! Data(contentsOf: fileURL)
return jsonFileData
}
来源:https://stackoverflow.com/questions/39815054/how-to-include-assets-resources-in-a-swift-package-manager-library