ylliX - Online Advertising Network
Disabling Xcode Asset Symbol Generation

Disabling Xcode Asset Symbol Generation


Xcode 16 added a property to asset catalogs to opt-out of asset symbol generation. This is especially useful for Swift Packages which had no way to disable the project settings they inherited.

Asset Catalog Symbol Generation – A Recap

Xcode 15 introduced a feature to create Swift, and Objective-C, symbols for colors and images in the asset catalog. Here’s the asset catalog in my main app bundle with the default accent color and app icon, to which I’ve added an image and color:

Asset catalog containing a blue accent color, empty app icon, yellow star image and yellow text background color

Using my custom color and image in a SwiftUI view without symbol generation:

VStack {
  Image("Star")
  Text("Hello, world!")
    .padding()
    .background(Color("TextBackground"))
}

Using a string for an asset catalog entry is error prone and there’s no help from autocomplete or the compiler. If I get the name wrong the image or color are missing when my app runs.

Starting in Xcode 15 I can rewrite my SwiftUI view to use the automatically generated symbol names for the image and color:

VStack {
  Image(.star)
  Text("Hello, world!")
    .padding()
    .background(.textBackground)
}

That has the advantage that my image and color names autocomplete and the compiler checks they are valid. If I rename the image in the asset catalog the compiler will now warn me:

Error type image resource has no member star

Note that Xcode generates the symbols when you build the target.

You can find the generated code in GeneratedAssetSymbols.swift. For Objective-C, import the GeneratedAssetSymbols.h header file.

The symbol generation is on, by default, for new projects but you can opt-out, and customise the scope, in the project or target settings:

Asset catalog compiler options

Xcode generates the color symbols as static properties of the ColorResource type:

// GeneratedAssetSymbols.swift
@available(iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0, *)
extension DeveloperToolsSupport.ColorResource {
  /// The "TextBackground" asset catalog color resource.
  static let textBackground = DeveloperToolsSupport.ColorResource(
    name: "TextBackground",
    bundle: resourceBundle)
}

The image symbols are likewise static properties of the ImageResource type:

@available(iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0, *)
extension DeveloperToolsSupport.ImageResource {
  /// The "Star" asset catalog image resource.
  static let star = DeveloperToolsSupport.ImageResource(
    name: "Star",
    bundle: resourceBundle)
}

Note that the initial letter of the symbol is lowercase even if the name in the asset catalog starts with an uppercase letter.

Framework Extensions

Xcode also generates extensions for SwiftUI, UIKit, and AppKit color and image types (though you can restrict the framework support in the build settings if you wish). For example, here’s the generated code for the SwiftUI Color type:

extension SwiftUI.Color {
  /// The "TextBackground" asset catalog color.
  static var textBackground: SwiftUI.Color { .init(.textBackground) }
}

Xcode generates the symbols for the module containing the asset catalog which means they also work for asset catalogs included in Swift Packages which inherit the settings. Unfortunately that created a problem in that there was no way to disable the symbol generation in a package.

Opt-out for Swift Packages

In Xcode 16, asset catalogs gained a new “Asset Symbols” property in the file inspector:

Asset catalogs now provide an inspector property for enabling system color and image accessors for generated asset symbols, which allows Swift packages to opt-in to generating these accessors. (113704993)

File inspector for asset catalog with asset symbols inherited (extensions on

There are three possible values:

  • Inherited. This is the default and inherits from the project/target settings. The inspector shows the value in effect.
  • Extensions On
  • Extensions Off

The last two settings override the inherited settings allowing you to opt-in/out of symbol generation for individual asset catalogs in Swift package modules.

That’s useful if the generated symbols clash with other names in the module or you prefer not to rely on Xcode generating code.

One reason you might want to create your own symbols is that the Xcode generated ones only have internal scope. If you want to access the assets outside of the package scope you’ll need to create your own public symbols (see Add resources to swift packages).

Learn More



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *