Swift Package Resources: Bundling Assets with Code

A Swift Package resource bundle is like a fanny pack for your code, letting you package assets like images and data files directly with your library. This makes your package self-contained.
WHY IT EXISTS Before resource bundling, Swift packages could only contain source code. If a library needed an image or a configuration file, it had to rely on the main application to provide it, breaking encapsulation and making the package harder to use. Resource bundling solves this by making packages truly self-contained.
THE MENTAL MODEL Think of a resource bundle as a fanny pack for your Swift package. The package contains your code, and the bundle is a dedicated container holding all the necessary accessories—images, sounds, JSON files, localization strings—that the code needs to function at runtime. Without it, your code can't find its assets.
HOW IT WORKS You define which files to include in your Package.swift manifest, typically by pointing to a "Resources" folder using the .process rule. The Swift Package Manager then compiles these assets into a special .bundle file that gets shipped with your package. Inside your package's code, you access this bundle through a special, auto-generated static property: Bundle.module.
WHEN TO USE IT Use resource bundles whenever you're building a reusable component that depends on non-code assets. This is essential for UI libraries with their own icons and NIBs, data processing modules that ship with default schemas, or any package that needs its own localized strings.
WHEN NOT TO USE IT Avoid using resource bundles for packages that are purely algorithmic and have no external file dependencies. Also, be cautious about bundling very large assets that would significantly bloat the library's size; for those, it might be better to download them on demand from a server.
ONE CANONICAL EXAMPLE To include an image named "icon.png" located in a MyProject/Sources/MyLibrary/Resources directory, you would first declare it in your Package.swift: .target(name: "MyLibrary", resources: [.process("Resources")]). Then, to load it in your library's code, you would write: let image = UIImage(named: "icon", in: .module, compatibleWith: nil). The key is using .module to ensure you're looking inside your package's specific resource bundle, not the main application's bundle.
Read the original → developer.apple.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.