Introducing xPal

In a previous post I talked about some methods for implementing macOS Mojave's Dark Mode. While we were adding Dark Mode support to Quids we found the process slow and error prone.

We thought; wouldn't it be cool if we could automagically generate our .xcassets asset catalog from our Sketch file?

xPal is a small tool that takes the artboards from a page in Sketch and generates an asset catalog for your Xcode project that contains all the colors named and grouped appropriately. Once your Sketch file has been prepared just drag and drop it onto the xPal window and it does the rest. Watch a demo here.

Download xPal here.

Implementing Dark Mode with macOS Mojave and Swift

With the latest macOS release, Apple introduced Dark Mode. Dark Mode changes the whole colour scheme of the OS to a darker, more subtle style. Not only does the OS change but so do the apps.

We recently added support for Dark Mode to Quids, our cryptocurrency Mac app. I was impressed with how easy Apple had made Dark Mode to implement and I expect to see a similar system come to iOS in the future.

If you have just used system colours such as NSColor.textColor, NSColor. selectedTextColor and NSColor.windowBackgroundColor, then your work is done!

However, you most likely have some custom colours. Here is an example of what our colour setup originally looked like:

internal extension NSColor
    internal struct Quids
    	internal static let buttonBackground = NSColor(deviceRed: 250.0/255.0, green: 250.0/255.0, blue: 250.0/255.0, alpha: 1.0)
        // ... etc ...

First step is to create a new Asset Catalog. Choose where you want to add the new file, right click, New File, Asset Catalog. Give it whatever name you want, I like to live on the edge and use Colors.xcassets.


Next you need to add a colour set. Do this by either right clicking on the asset catalog’s left list view or by clicking the + button in the catalog’s bottom left and select “New Color Set”


Now you’ll have something that looks like this:


First things first, set the name. On the right side where it says “Name: Color” set this to whatever best describes your colour. I’m going to call mine ButtonBackground.

As it stands, this colour set is only setup as having no appearance, meaning that no matter what colour mode the user has, our ButtonBackground colour will always be the same.

On the right, select the “Any, Dark” appearance.


You’ll see another colour swatch appear. Clicking a swatch will let you set the colour values:


With the colours set, the last step is to update our code:

internal extension NSColor
    internal struct Quids
    	internal static let buttonBackground = NSColor(named: "ButtonBackground")!
        // ... etc ...

That’s it! We’re now all setup to use the colour in our app…

Using The Colour

If you’re using a standard control that takes an NSColor, for example NSTextField and NSWindow then all you need to do is set our new colour:

self.textField.textColor = NSColor.Quids.buttonBackground
self.window.backgroundColor = NSColor.Quids.buttonBackground

However, if you’re doing something a little more custom, like setting a CALayer’s background colour:

self.view.layer?.backgroundColor = NSColor.Quids.buttonBackground.cgColor

This won’t work. Never fear! There a few hooks that get called when the OS’s colour mode changes:

// NSViewController

override func updateViewConstraints() 
    self.view.layer?.backgroundColor = NSColor.Quids.buttonBackground.cgColo

// NSView

override func updateLayer()
    self.layer?.backgroundColor = NSColor.Quids.buttonBackground.cgColor

override func layout()
    self.layer?.backgroundColor = NSColor.Quids.buttonBackground.cgColor

override func updateConstraints()
    self.layer?.backgroundColor = NSColor.Quids.buttonBackground.cgColor


We've recently released xPal which automagically generates a Xcode color asset catalog from a Sketch file!

Xcode 10 Crash - device has no defaultDisplay

Upgrading to Xcode 10 has been pretty smooth apart from one issue. I'm unsure what causes it but the Simulator can constantly crash on startup with the error:

Device XXXX is available but has no defaultDisplay

Running this command fixed the crash loop for me:

sudo killall -9

Thanks to this Stack Overflow post!

Quids Beta 2

We've just released Quids Beta 2 🎉

Read all about the new features here and register for beta here!

Crypto Icon API Service

Originally posted on Medium.

We’ve just released (and open sourced!) the web service we built for serving the cryptocurrency icons maintained by the Cryptocurrency Icons project.

The service was originally built for use in Quids for Mac to avoid bundling every icon with the client and having to make a new release everytime we supported a new currency. Instead, we use this service to dynamically accept the SVG source and render a PNG, using any of the included icon styles provided and at any size we need.

We have also released the Swift library we use in Quids to build the URLs.

The service is completely free to use but is provided “as is”. If you wish to guarantee uptime (like we do for Quids), I recommend deploying your own instance. The Github README has a Heroku button to make deploying your own instance of the service really simple.

Bitrise + Bugsnag

Since Buddy Build was bought by Apple (congrats!) I've been keeping an eye out for a possible alternative. Not because Buddy Build has become rubbish since the acquisition (it's still awesome) but because if it is shut down and absorbed into Apple (e.g. TestFlight) then I would have to spend a ton of time migrating client projects somewhere else.

So for new projects I have been using Bitrise. It is a lot more configurable than Buddy Build and definitely took a bit longer to get setup, but once I got my head around it, it became super powerful.

One out of the box "integration" that was missing was uploading dSYM files to Bugsnag. I've written a previous post about how I got this working with Buddy Build. Getting it to work with Bitrise is very similar:

Firstly you need to head over to the Workflow Editor. After your Xcode Archive & Export step, insert a Script step.

Under the config menu, set the working directory to $BITRISE_XCARCHIVE_PATH.

Then set the script content to:

#!/usr/bin/env bash
# fail if any commands fails
set -e
# debug log
set -x

ls **/*.dSYM/Contents/Resources/DWARF/* | while read line; do
    echo "Uploading $line"
    echo "Running: curl -F 'dsym=@$line'"
    curl -F "dsym=@$line"

Quids Beta


We've just sent out our first beta build to our Product Hunt subscribers! Full blog post here.

If you want to try Quids just sign up here 😺