10 August 2015 4min read

Generating an Objective-C color palette from Sketch

Last week I had to made some changes on the colors of the WorkAngel app. The colors of that app are retrieved through an object called ThemeColor (we have another for the fonts). That object is the concrete implementation of a Theme protocol that defines the names of all the different colors that the app needs.

As it’s not the first time that I had to change the theme itself, and I suspect that it won’t be the last one, I thought that maybe I could build a small script to generate the theme automatically.

The theme is done by our designers in Sketch. It surprises me that the theme itself is so good looking.

Sketch Color Palette

Just with colors and names that make more sense :P I totally made up that theme just to use it as an example.

Knowing that Sketch has a rich plugin community I thought that it would be the best approach. Build a plugin that the designers can use to generate and send us the files. Then I will only have to replace them and the PR will be ready ^^.

My first stop was in the documentation page: Sketch Plugins Basics. It seemed like the API is well documented and the introduction is also well explained. Start messing with Sketch plugins is actually pretty easy.

The best part is that Sketch uses CocoaScript which allows you to use the Cocoa APIs in Javascript. You can even write Javascript as if it was Objective-C! Square brackets included!

Before spending the time to implement anything I asked in Twitter if there was something similar. I knew that the answer would be no, because I doubt that nobody else is doing the color palettes in the exact same way, but Ricardo pointed me to a plugin that I used later as a guide to start.

At the end I didn’t have time to lose in that, so I made the changes manually. But this past weekend the idea was still in my mind so I decided to spent a couple of hours to see how Sketch plugins are developed and what I could do with it.

The first thing I noticed is that the documentation was not as good as I thought. There are quite a lot of plugins out there that you can read, and having the Cocoa APIs available make things easier, but I have to say that the documentation could be improve. I’ve also seen that a lot of the plugins that exist use a different (old?) structure, different form the Bundle Plugin that I wanted to use.

After having things more clear I started typing some code to try to navigate through the layer hierarchy. At this point I spend A LOT of time fighting to make a for..in loop. Yes, just a basic for :( The thing is that I wanted to iterate Cocoa arrays in Javascript, which was posible until version 3.0.2. Luckily I found the Changelog where they mention this. You have to call .array() to bridge the arrays.

I ended up using Cocoa enumerators tu loop the arrays:

var loop = [layers objectEnumerator];
while (layer = [loop nextObject]) {

After this I made good progress on finding the colors in the Sketch document. I have to say that is very unproductive to use a scripting language without any kind of type checking. I configured Atom with a linter that at least provided me some syntax checking, but still, I don’t know why people wants to work with this kind of system. Having to use Console.app to look for logs was barbaric. Even more when I discovered that any syntax error is reported as an index out of bounds exception.

8/8/15 13:17:34,055 Color Theme (Sketch Plugin)[42500]: Caught script exception: *** -[__NSArrayM objectAtIndex:]: index 211 beyond bounds [0 .. 128]

After having all the data needed from Sketch I was getting closer to the end. I just had to generate some strings and save the files. For that I thought that the easiest way would be to have template files and use a Javascript template engine as Mustache. I didn’t need anything fancy, just something that would let me define a couple of iterations and access to object properties.

But knowing that anything could fail I decided to import mustache.js and run the easiest example. And obviously… it didn’t work. I lost almost an hour with this, trying different ways of importing, even modifying the mustache.js source code itself. But with no luck. I was really disappointed. I thought that with all this hype about Isomorphic Javascript this kind of libraries would be easy to integrate. And I guess that they are, but something was going wrong with CocoaScript, or maybe it was totally my fault.

The fact is that I ended up generating more strings in code than I wanted. And having the file template with just one easy to find sentence that I replaced.

template.replace("{ {implementation}}", gen);

Well, it does the job.

With this I had a script that generated a Theme.m file. Mission accomplished.

The script is not finished at all, there are many things to improve. But I didn’t want to waste more time in it without knowing if I would needed. But now, the next time that I have to change the colors from the App I know that I can use the plugin with just some final touches.

And more important, I have satiated the thirst of making a Sketch plugin.

If you are curious you can check the plugin on GitHub.

If you enjoyed this post

Continue reading