Manage Your iOS Resources Type-Safely with R.swift

A common frustration with the iOS platform is that resources are accessed using magic strings. In practice, this means you'll find out if an image, icon, localized string etc. exists at runtime. Either by seeing what you were hoping for or getting a hard crash. Let's fix this by introducing your new best friend - R.swift.

Written by 

The developers behind the iOS platform should take a close look at how Android is handling resources (localized strings, images, icons, etc.). No resource references using magic strings - everything is statically typed as it should be. But don't worry - the iOS community comes to the rescue by providing a library for this missing feature in the platform.

In this post, we will uncover the tool R.swift that allows for accessing resources in a clean and type-safe way - and how you incorporate this tool in your iOS projects.

Why should you use R.swift?

R.swift provides strong typed, autocompleted resources like images, fonts and segues in Swift projects.

Let us look at an example to help paint the picture:

// Traditional way of accessing assets using strings
// Consider what should happen if the image isn't there at runtime
lazy var unsafeBackgroundImage: UIImageView = {
    guard let image = UIImage(named: "matteo-catanese.jpg") else {
        fatalError("Ouch, it wasn't there.") 
    let imageView = UIImageView(image: image)
    imageView.frame = containerView.frame
    return imageView

// New way of accessing assets using R.swift
// You'll get an error at compile-time if the image isn't there
lazy var safeBackgroundImage: UIImageView = {
    let imageView = UIImageView(image: R.image.matteoCatanese())
    imageView.frame = containerView.frame
    return imageView

Not only will you get an error compile-time, if you're referencing incorrect resources, but you will have autocompletion, so you never again have to guess the exact name of that icon, font, etc.

The way R.swift works is by scanning the project for resources during a build phase. It then generates an R.generated.swift file containing one struct per resource type (R.image, R.font, R.string and so on) with properties for each specific resource in the project.

R.swift currently supports the following resources: images, custom fonts, resource files, reusable cells, localized strings, storyboards, segues, and nibs.

Setting up R.swift using Mint

My preferred way of setting up R.swift in a project is by using Mint. Mint is great for most CLI packages that you would normally download with Homebrew, as you can easily download and run a specific version of a package. This way, we can easily align each team member's development environment and reduce those annoying "it works on my machine"-issues.

First off, install Mint with Homebrew (as ironic that may be) by running brew install mint in your terminal. Then you want to add a so-called Mintfile in the root of your project. It should contain one line:

Normally, you would add a library by using a format like mac-cain13/R.swift@5.1.0 but support for Mint was added recently and seems to still have some early quirks. The line above will do the job for now.

You'll then need to run mint bootstrap in the root of your project to install R.swift. Now, open the project and add the package R.swift.Library to your project via Swift Package Manager. This package will provide types to support the R.swift code generation in your project.

Once that's installed, you need to run the R.swift tool from a build phase, so that new resources become available with R.swift after each build. Go to the target of your app, select Build Phases and create a new phase just above Compile Sources. Paste the following script to be run by the build phase:

if mint list | grep -q 'R.swift'; then
  mint run R.swift rswift generate "$SRCROOT/YourProjectName/Resources/R.generated.swift"
  echo "error: R.swift not installed; run 'mint bootstrap' to install"
  return -1

Next, you want to add this line to the Input Files:


And this line to the Output Files (assuming you want the R.generated.swift in a Resources folder).


The build phase should look like this:

Finally, create a Resources group in your project. Build your project, and in Finder, you will now see an R.generated.swift in the root folder.

Go ahead and drag the R.generated.swift file into your project and uncheck Copy items if needed. You should end up with a folder structure similar to this:

Optional: Add *.generated.swift to your .gitignore file to prevent merge conflicts.

We're done! Now, you should have autocompletion by using R.swift in your codebase.


There are various alternatives to R.swift. The most prominent one is SwiftGen, but the main reason that I use R.swift is that it inspects the Xcodeproj file for resources instead of asking you for files to use. That makes my part of the process a bit easier.

It also seems that R.swift is more actively maintained at the moment. The result is fairly similar, and if you're currently using SwiftGen or another alternative that gets the job done, you might as well stick to that.


That's it! We covered how you get started with R.swift in your iOS projects to achieve:

  • Compile-time validation - no more incorrect strings that will crash your app at runtime
  • Free autocompletion - never have to guess an asset name again

Thanks for reading. See you in another article!

Share this post


You may also like


Architecting an Analytics Service for iOS Apps

Monitoring the behavior of your app’s users is critical to the success of your app. If the only feedback you get from your users are App Store review, now is the right time to start using analytics. We’ll go over how you create an analytics service that’s modular and easily extensible using a clean iOS architecture.


Continuous Integration Using GitHub Actions for iOS Projects

Github Actions are finally publicly released! It’s an opportunity to easily enable continuous integration in your projects on GitHub, so here’s how you set it up for your iOS projects to perform automated code validation and testing on pull requests.


Native App vs React Native App – What Should You Choose?

Gone are the days where the only options in mobile app development were native iOS and Android. The choices are broader nowadays, and frameworks have popped up with React Native being the most popular alternative. So what approach should you choose for your next app?