Creating Slick Color Palette APIs
The work of writing maintainable code is an ongoing endeavor and some of my favorite problems to solve are ones that build maintainable systems. Maintainable systems are ones you can learn once, easily manipulate, and ideally take from project to project. My favorite part of building maintainable systems is that it minimizes the amount of work I need to do when starting a new project, and like it is for many programmers hitting ⌘ + ⇪ + N to start a new project is one of the most satisfying feelings in the world for me.

A color palette is something every well-designed app needs, and it turns out there are a lot of ways to solve this problem. If you don't yet have a good sense for how to construct a color palette, I highly recommend this post by Refactoring UI that explains the fundamentals of a good color palette. Generating a good color palette can be tricky if you’re new to the practice and can require some trial and error, so if you’d like a shortcut a tool like Coolors is a great starting point.

I've spent years iterating on approaches to codifying color palettes in my iOS and macOS apps, seeking to create one that’s flexible, scales well, and is easy to understand, landing on the version we’ll explore below. We'll be able to leverage asset catalogs, create a clear sense of hierarchy, provide statically typed semantic colors, even take advantage of the built in features of SwiftUI. As a bonus, if you're working with designers, your palette will be so straightforward to modify that a designer can submit a pull request to change colors without ever involving you.

 

Considering we'll be leveraging asset catalogs, the first step should be pretty intuitive, we should create an asset catalog to hold our color palettes.


As I was piecing together different instructions and ideas this second step confused me, so I'll spare you the misery. You're going to want to make a different folder for each color palette you create, and you can do that by right clicking in the asset catalog and selecting New Folder.


Now it's time to create our color palettes. I'm showing you the Night palette I created for my app, and below it are Spring, Summer, and Winter. Each palette has the same name but all of the colors are named the same, each palette will have colors named background-alt, primary, quaternary, etc.


Do not miss this incredibly important step, guide your eyes towards the pink arrow on the right side of the image. You must select the folder you're adding colors to and check the Provides Namespace checkbox. This is what will enable our code to have a clear and consistent naming structure, matching the folder’s name to our theme’s name.

 

Now that we've got our asset catalogs setup, we're ready to write some code. We'll start by constructing a new Palette struct, and populating it with some Colors that we'll reference across our app.

extension Color {

    struct Palette {
        let name: String

        var mainBackground: Color {
            self.assetCatalogColor(named: "background-main")
        }

        var midBackground: Color {
            self.assetCatalogColor(named: "background-mid")
        }

        var alternativeBackground: Color {
            self.assetCatalogColor(named: "background-alt")
        }

        var primaryText: Color {
            self.assetCatalogColor(named: "text-primary")
        }

        var alternativeText: Color {
            self.assetCatalogColor(named: "text-alt")