How to turn XCode color assets (.xcassets) into UIColor extension

Pichratanak Ky
4 min readFeb 26, 2020

Introduction

I’d like to share an interesting way to turn your XCode color assets (.xcassets) into UIColor extension that you can freely use everywhere within your XCode projects. It may sound strange at first because we already have access to all those colors within in code and .xib but WHY?!! (You may asked!!!)

Here what’s annoys me 🤬

Say you have a number of colors in .xcassets that can be access in Swift/ObjC and xib. Most likely, below code is how we’re going to access it in Swift.

// 1. Direct UIColor access
UIColor(named: “contentBlue”)
// 2. Create a nicer wrapper and put it in a method or extension
func contentBlue() -> UIColor {
return UIColor(named: “contentBlue”)
}
.xcassets sample file

This works most of the time, but to me, the problem is that we give it raw String value and in fact, most of us will copy and paste that String value from color assets or put it within a method with more friendly name. Moreover, in real world scenario, it is a little manual and repetitive process. It works in most of the cases but I personally feel ineffective. Plus, using String as reference, there is a small chance that it might not be able to find it. Wouldn’t it be great if we can access each color in the asset like this?

UIColor.contentBlue
UIColor.contentGreen
UIColor.contentPink
UIColor.contentYellow
...

Here comes solution 💡

Here what’re we gonna do: turn your .xcassets into UIColor extension and easily access it everywhere using dot syntax rather than String. We’re going to use SwiftGen with customize template to read all colors in .xcassets and translate into Swift.

1. Install SwiftGen

You can copy and run below command in terminal or you can go follow instructions to install SwiftGen here yourself.

$ brew update
$ brew install swiftgen

2. Create SwiftGen template

We will use this template format to generate UIColor extension class out of .xcassets file. Create a new file in your proj directory and called asset-to-color-extension.stencil and place this whole script in from here. Feel free to make changes to match your project requirements.

3. Create SwiftGen .yml

This file will be use to tell SwiftGen where are the input and output files along with our customize template for file generation. Create a new file in your proj directory and called it swiftgen.yml and place this text in:

xcassets:
inputs:
- XCColor/Colors.xcassets // 1
outputs:
- templatePath: asset-to-color-extension.stencil // 2
output: XCColor/UIColorExtension.swift // 3
params:
enumName: UIColor
publicAccess: true
allValues: true
  1. This is your color assets’s directory. Make sure you give the actual relative path to your file.
  2. This is the name of the template file that we’ve created earlier.
  3. UIColorExtension.swift will be generated in the same color as Color.xcassets. Feel free to change it.

4. Run SwiftGen

In terminal run swiftgen , once done, you’ll find new file in directory that we’ve specified in swiftgen.yml

swiftgen

What you have to do now is to drag that file into XCode proj and voila 😎🙌🏻. As you can see, this file is very simple. Basically, it is just an extension of UIColor that has all the static properties as if we would do ourselves. Also there is a property that return all the custom colors and their names that we generated from Colors.xcassets which is handy in my opinion. On top of that, we can also reference it with Objective-C 😲.

Every colors will be name base on what we have in the .xcassets file

So next time if we add or remove colors from Colors.xcassets, we can simply run swiftgen and it’ll get updated 👏🏻👏🏻👏🏻.

Demo project file

You can also find this sample iOS proj under my github repo below. It also demonstrate on how to use it as well which is very simple.

Demo proj

Where to go from here

Feel free to make changes to SwiftGen template to match your needs. I’ll leave that imagination up to you. In my case, I created this generator as a pod so that I can reuse on multiple projects. The template is slightly different but the idea remains the same.

--

--