I have a module (A) that has two structs.
public struct CodeColor {
public init() { }
public let value = SwiftUI.Color(#colorLiteral(red: 0.8549019694, green: 0.250980407, blue: 0.4784313738, alpha: 1))
}
public struct AssetColor {
public init() { }
public let value = SwiftUI.Color("Legacy/Material/Gold", bundle: .module)
}
The preview is working like a charm:
The second module (B) should use the previous one (A) as a dependency to load colors from:
import A
public struct CodeColor {
public init() { }
public var value: SwiftUI.Color { A.CodeColor().value }
}
public struct AssetColor {
public init() { }
public var value: SwiftUI.Color { A.AssetColor().value }
}
But as soon as it touches the assets from module (A), the preview crashes:
Can not preview in this file. Failed to update preview.
RemoteHumanReadableError: Failed to update preview.
The preview process appears to have crashed.
Error encountered when sending 'previewInstances' message to agent.
==================================
| RemoteHumanReadableError: The operation couldn’t be completed. (BSServiceConnectionErrorDomain error 3.)
|
| BSServiceConnectionErrorDomain (3):
| ==BSErrorCodeDescription: OperationFailed
Note: The stranger thing is that the exact B preview code is working if it is in an actual app (not another package)
Here is the full code on github
I found a solution in the developer forum:
Link
https://developer.apple.com/forums/thread/664295?login=true#reply-to-this-question
NOTE - LOCAL
The solution is for local package. You define
let bundleNameIOS = "LocalPackages_TargetName"
let bundleNameMacOs = "PackageName_TargetName"
REMOTE (Packages from GitHub e.g.)
If you have your package on GitHub and fetch it remotely, you can't define local packages and you have to slightly change it to:
let bundleNameIOS = "TargetName_TargetName"
let bundleNameMacOs = "TargetName_TargetName"
Example
Here is a full implementation example, you have to put it inside your package with the resources:
// Inside your package with the resources:
// Extend Bundle to access it in other packages
extension Bundle {
// public static let assets = Bundle.module
// Updated with workaround
public static let assets = Bundle.myModule
}
Define your bundle
private class CurrentBundleFinder {}
extension Foundation.Bundle {
static var myModule: Bundle = {
/* The name of your package. You may have same PackageName and TargetName*/
let bundleNameIOS = "TargetName_TargetName"
let bundleNameMacOs = "TargetName_TargetName"
let candidates = [
/* 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: CurrentBundleFinder.self).resourceURL,
// -> Optional UI Tests
/* Bundle should be present here when the package is used in UI Tests. */
Bundle(for: CurrentBundleFinder.self).resourceURL?.deletingLastPathComponent(),
/* For command-line tools. */
Bundle.main.bundleURL,
/* Bundle should be present here when running previews from a different package (this is the path to "…/Debug-iphonesimulator/"). */
Bundle(for: CurrentBundleFinder.self).resourceURL?.deletingLastPathComponent().deletingLastPathComponent().deletingLastPathComponent(),
Bundle(for: CurrentBundleFinder.self).resourceURL?.deletingLastPathComponent().deletingLastPathComponent(),
]
for candidate in candidates {
let bundlePathiOS = candidate?.appendingPathComponent(bundleNameIOS + ".bundle")
let bundlePathMacOS = candidate?.appendingPathComponent(bundleNameMacOs + ".bundle")
if let bundle = bundlePathiOS.flatMap(Bundle.init(url:)) {
return bundle
} else if let bundle = bundlePathMacOS.flatMap(Bundle.init(url:)) {
return bundle
}
}
fatalError("unable to find bundle")
}()
}
Accessing package A resource in package B
You can now access the resource from package A inside package B like:
let example = UIImage(named: "Exampe", in: Bundle.assets, with: nil)!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With