Hi, for projects we used to use one SPM module for all application resources (Texts, Images, Fonts, ..) and use swiftgen to expose them safe and publicly for other modules.
I tried replacing swiftgen with the new resource catalog generation option in Xcode 15 and ran into not being able to make the generated structure public for other modules.
Is it possible to affect the generation with some parameter to add public access?
extension ImageResource {
/// The "img_error_generic" asset catalog image resource.
static let imgErrorGeneric = ImageResource(name: "img_error_generic", bundle: resourceBundle)
}
This is a great limitation and basically makes it unusable for us. Do you think we could write a Publify macro that goes through all the internal members of the ImageResource extension and exposes them as public with a certain prefix? The execution of the macro would have to happen after the asset symbol generation itself but I think this is the case. Something like
extension ImageResource {
/// The "Share" asset catalog image resource.
static let share = ImageResource(name: "Share", bundle: resourceBundle)
would be peered with
public extension ImageResource {
/// The "Share" asset catalog image resource.
static let iconShare = .share
As far as I am aware this is not possible since the macro must be applied to the ImageResource struct itself and cannot be applied to e.g. a extension since otherwise it won't see the generated properties.
My company has a separate swift package for our design system and reusable UI components. So all of our colors and images are also in this swift package.
Unfortunately because of this limitation, the Xcode asset catalog code gen is not useful for us.
Just a workaround, but to get around this I just expose resources via properties that I define. So if my UI library contains an image asset named "back_arrow", I'll expose it publicly by defining a static property on a UIImage extension using the resource initializer.
public extension UIImage {
static let backArrowIcon = UIImage(resource: .backArrow)
}
This isn’t much of a workaround as you have to do it by hand. You are better off turning of Xcode code gen and using SwiftGen or writing a build plugin.
Yep. It's hard to believe that there is 1. no improvement in Xcode 26.0 (afaict) and 2. you can duplicate this post and change the title to Xcode 26 generated LocalizedStringResource with public access
FB18574624: Generating Asset symbol constants with public access in a Swift package
I’m using an Asset catalog in a Swift package to define colors that are to be used in other Swift packages.
Currently there seems no way to make the extensions to „DeveloperToolsSupport.ColorResource“ (and the like) public, nor to disable the generation at all.
This is cumbersome. As a workaround, I write the extension to Color/UIColor myself, but then these colors are to be used differently when they come from a package (Color.skyBlue) vs. when they come from the local package (Color(.skyBlue) - I’d prefer the ColorResource style).
Maybe a 2nd option „Public Asset Symbols“ next to „Asset Catalog » Asset Symbols“ in the .xcassets that would apply both to ColorResource / Color extensions?
Until this is “fixed” in Xcode, I’ll consider writing the extension on Color etc like is mentioned above. I’d prefer that over using heavier dependencies like SwiftGen - which come with their own issues from time to time.
Just wondering if this extra public extension is something that could be written using a more lightweight build script, or perhaps some Xcode extension?
Note: I’m using assets in an external Swift package. Maybe things work slightly differently if using external targets vs external Swift packages?
So as I was using packages for assets, I started out writing a plugin and script mimicking the behavior of SwiftGen; parsing .xcassets directories, assembling their contents to a public interface, pre-build, only to realize that SwiftGen already has such a plugin for packages, so I guess that's what I will try next.