Accessing Asset Catalog resources (colors, images, strings, etc.) in Swift currently relies on string-based APIs such as UIColor(named:), which provide no compile-time safety, no autocomplete, and fail silently at runtime when assets are missing or renamed.
As a result, most production teams rely on third-party code generation tools (e.g. SwiftGen) to generate typed accessors for asset catalog entries. This pattern is extremely common but lives entirely outside the Swift toolchain.
Provide an official, first-party mechanismâideally via SwiftPM Build Tool Pluginsâto generate typed Swift accessors for asset catalog resources at build time.
Correct me if Iâm wrong, but the compiler already generates ImageResource, ColorResource and LocalizedStringResources (where marked for generation in String Catalogs), which can be converted to these types with framework initializers.
Yes, Iâve since realized that this does exist on the SwiftUI side, and Apple has provided bridging APIs so those generated resource types can also be used from UIKit (e.g. UIImage(resource:), UIColor(resource:)).
That said, it would be nicer if this were integrated directly and idiomatically into UIKit, for example with something like:
UIImage.Assets.myImage
UIColor.Assets.myColor
This would make the distinction explicit and provide a UIKit-native, discoverable way to access custom images and colors. While UIImage(resource: .myImage) does work, the current approach still feels SwiftUI-driven rather than UIKit-first.
Given that the vast majority of production codebases are still built with UIKit (especially larger, long-lived apps), having first-class, discoverable asset APIs would significantly improve the developer experience for teams that are either staying with UIKit or migrating gradually to SwiftUI.
Yes, It works in Swift Packages, but the project settings are per target. Youâll need to enable the âGenerate String Catalog Symbolsâ build setting in your packageâs .xcconfig or set it directly in the package manifest:
.target(
name: "MyLibrary",
swiftSettings: [
.define("ASSET_SYMBOLS_ENABLED") // or via buildSettings dictionary if needed
]
)
If youâre using asset catalogs in a package, the image/color symbols should generate automatically with the Xcode 15+ settings enabled.
That said, the API you get (String(localized: .welcomeTitle), UIImage(resource: .logo)) still feels SwiftUIâfirst. A UIKitânative wrapper like UIImage.Assets.logo would make migration and mixedâcodebase work much smoother.
Have you tried "Generate Swift Asset Symbol Extensions: YES"? It gives you almost what you want:
UIImage.myImage // this form requires Generate Swift Asset Symbol Extensions: YES
UIImage(resource: .myImage) // this works without the above key
Ditto with the colours.
There is no equivalent of "Generate String Symbol Extensions" for strings AFAIK, but compared to a hypothetical String.myKey the String(localized: .myKey) form is "superior" in that it allows to easily search for all "String(localized:" instances across source files.
A followup question though: can't see how to use this in packages, is it available there?
I gave it another go â turns out it works out of the box for image/colour assets and strings.
The only thing that doesn't work is using the extension form of image/colours.
This works (from within my package):
String(localised: .myString) // if string is inside "Localizable.xcstrings"
String(localised: .OtherTable.otherString) // if string is inside "OtherTable.xcstrings"
UIImage(resource: .myImage) // regardless of the asset file name
UIColor(resource: .myColor) // regardless of the asset file name
This doesn't work (from within my package):
UIImage.myImage // requires "Generate Swift Asset Symbol Extensions: YES"
UIColor.myColor // requires "Generate Swift Asset Symbol Extensions: YES"
This doesn't work either (from normal app target either), although I guess this is expected:
UIImage.AssetFileName.myImage // does not ever compile (expectedly?)
UIColor.AssetFileName.myColor // does not ever compile (expectedly?)
UIImage(resource: .AssetFileName.myImage) // does not ever compile (expectedly?)
UIColor(resource: .AssetFileName.myColor) // does not ever compile (expectedly?)
Is that possible at all? I tried that but there's no "target" shown for my package, and setting xcconfig file on it's "project" level doesn't seem to do anything.
You mean this key specifically: "ASSET_SYMBOLS_ENABLED" ? I don't see it documented anywhere. For image/colour extension generation I tried setting:
but that doesn't work (besides it feels wrong to use it with .define(...), e.g. it doesn't allow setting the key to false, other than commenting it out).
"or via buildSettings" - what exactly is this? I do not see this parameter or ability to change build settings for my package via Xcode UI.
Relevant keys for xcconfig files (or Xcode settings in UI)
Thanks for the detailed follow up you've essentially reverse engineered the exact workflow I had in mind. It's great to confirm that UIImage.myImage works once Generate Swift Asset Symbol Extensions is enabled. That's almost what I was hoping for.
Honestly, I wasn't even aware this option existed and I suspect many UIKit developers aren't either. I've seen numerous projects still using manual enum wrappers or raw UIImage(named:) strings, which suggests this feature isn't discoverable enough in its current form.
The remaining friction especially how this setting isn't easily exposed or consistently configurable in Swift Packages highlights the kind of tooling gap that would benefit from official, first party support. Ideally, these generated symbols should be:
Discoverable: available via autocomplete without needing to dig through build settings.
Consistently configurable: whether in an app target, Swift package, or Xcode project.
UIKitâidiomatic: even with UIImage.myImage, the flat naming still feels like a generated artifact rather than a designed UIKit API.
What I'm advocating for is taking this existing but tuckedâaway capability and making it a polished, intentional part of the UIKit development experience something like UIImage.Assets.myImage that feels native, grouped, and designed rather than generated.
Note that currently you won't be able having the same image/colour name in two assets, so this is currently no-go (if specifying asset name was possible to begin with I mean):
Until Xcode asset support is improved there's this hack, which brings you half-way to grouping (but without any safety or checking you grouped things right):
extension UIImage {
typealias FirstAssets = UIImage
typealias OtherAssets = UIImage
}
...
UIImage.FirstAssets.firstImage
UIImage.SecondAssets.secondImage
UIImage.FirstAssets.secondImage // no checking here
Personally I'd welcome the addition of some tooling support for icon / colour asset symbols being drawn inline in Xcode (like we had with image and colour literals (in fact I am still using those for the benefit of this WYSIWYG aspect (despite image literals not being type safe ))).
Literals in text form (we already have this):
func theTest() {
let image = #imageLiteral(resourceName: "myImage")
let color = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1)
}
The improvements you are suggesting are useful quality of life improvements. The best place for them would be feedback assistant report (for "Developer Tools & Resources" / "Xcode").
Thanks for the insights. The typealias hack is clever, and the collision issue really shows why current symbols feel like a workaround rather than a designed API.
Inline previews for asset symbols in Xcode would be a huge discoverability win. I'll file this in Feedback Assistant as you suggested. Even if full UIImage.Assets.myImage grouping isn't feasible yet, better previews and clearer package configuration would go a long way.
Appreciate the deep dive this has been super informative.
Since discoverability has been mentioned as a significant issue, I did want to highlight that namespacing (e.g. UIImage.Navigation.logo and UIImage.Homescreen.logo) can be achieved.
In the asset catalog you can group your images/colors by namespaced folders by either making one directly via the new menus or selecting existing folders and ensuring the âProvides Namespaceâ checkbox ticked in the Attributes Inspector. The generated symbol will then be namespaced as well.
Great find, thank you for sharing this. It is exactly the API pattern I had in mind.
I did search for this approach but could not find any documentation or tutorials covering it. It seems this feature has not reached broader awareness yet. Even LLMs do not mention it, and most discussions still point to string literals or third party generators.
For a feature like this to truly benefit the community, it needs to be more discoverable. Right now, teams may keep using workarounds simply because they are not aware that built in namespacing exists.
Correct, those assets donât clash and is the exact purpose Asset Catalogs have supported namespacing for a long time. Itâs with noting that namespaces are nothing new as you could use them with the string APIs too e.g. UIImage(named: "Namespace/image")
While Iâm sure there is probably some upper limit to how many namespaces can be nested, Iâve never reached one, so you could end up with something like UIImage(named: "Homescreen/AB/Modern/Icons/user") which in the new symbols would be UIImage.Homescreen.AB.Modern.Icons.user
This is still all internal though isnât it ? Meaning you canât really put all your shared resources in a single module that you share without manually exposing public getters