Swift Protocols are great. They allow us to express the idea of expecting a set of functionality, without needing to expect a specific concrete type. Today we'll look at creating a Protocol to make working with colors in our apps a bit more flexible. Let's dive in. 🏊

We'll start by creating a new Protocol, giving it a conventional name, and require just one read-only property from our conforming types. This property will always return a UIColor.

public protocol ColorConvertible {
  var colorValue: UIColor { get }
}

Now, let's try this new Protocol out by creating an enum that represents the different colors we use in our app:

public enum SpaceshipsColors : String {
  case white = "FFFFFF"
  case red = "E2574C"
  case gold = "EFC75E"
  case darkTeal = "314D5B"
  case lightTeal = "3CB39E"
  case spaceGray = "233640"
  case aluminum = "6A838D"
  case black = "000000"
}

Looking pretty good, now let's extend our enum to conform to ColorConvertible.

We're using Hue here (Bite #195) to convert our hex color code Strings into UIColors.

extension SpaceshipsColors : ColorConvertible {
  public var colorValue: UIColor {
    return UIColor.hex(rawValue)
  }
}

Now we can reference colors in our code by name, and get full autocompletion when typing them. Using our new Protocol is super simple, let's make a quick UIView subclass to show it off:

class SpaceshipNameHeaderView : UIView {
  var nameLabel: UILabel
  var nameTextColor: ColorConvertible? {
    didSet {
      nameLabel.textColor = nameTextColor?.colorValue
    }
  }
}

It'd be nice if we could still supply "one-off" UIColors as well. No problem, let's simply conform UIColor itself to be ColorConvertible. We can just return self:

extension UIColor : ColorConvertible {
  public var colorValue: UIColor {
    return self
  }
}

Finally, we can use it like this:

let hv = SpaceshipNameHeaderView()

// works!
hv.nameTextColor = UIColor.black

// works just as well!
hv.nameTextColor = SpaceshipsColors.aluminum

Swift Protocols can help us write code that is both expressive and quite flexible. They can take a while to get a handle on, but understanding them is a key step towards unlocking the full power of Swift.