Usage Commands Cloud Contributors

Accessing resources

Depending on the target product (e.g. app, framework), resources are accessed differently. For example, if we are trying to get an image that is part of an app target, we get the image from the Bundle.main. Conversely, if the image is part of a framework, we access it from the Bundle that represents the framework, Bundle(for: FrameworkClass.self).resourceURL. Having an inconsistent interface for accessing resources complicates moving code a resources around.

Moreover, as you might know, libraries can’t contain resources - only frameworks can. On iOS, this often leads projects to use dynamic frameworks instead of static libraries, and in some cases, add custom build phases that copy resources from dependencies into the final product (app). Resorting to this setup is not ideal because it introduces side effects, complicates the maintenance of the project, and makes the setup hard to reason about.

A consistent way for accessing resources

Tuist solves this by generating a Bundle extension for accessing the right bundle depending on the type of target. For example, given a target framework MyFeature, you’ll be able to get the right bundle with:

let bundle = Bundle.module
Copy the content

Furthermore, we support defining resources in products that don’t support it (e.g. libraries). For those, we generate an associated bundle target (e.g. MyFeatureResources.bundle) that contains all the resources. The bundle ends up being copied into the final product bundle that contains compiled target.

Strongly recommended

Accessing the resources this way is not mandatory, yet we recommend it strongly. It'll ease making changes in your project like turning a library into a framework.


Tuist also synthesizes accessors for Objective-C. In this case, the Bundle needs to be accessed using the target name to avoid name conflicts:

NSBundle *bundle = [MyFeatureResources bundle];
Copy the content

By using this website, you agree to our cookie policy.