Swift: Printing an Array of enum

It was just recently that I discovered a cool little feature that allows you to describe Objects, structs and enums in Swift. It’s called the Printable protocol and it’s part of the Swift’s standard library.

Let’s describe a situation when it is handy. Imagine that you have an array that represents a magazine table of contents. This array holds not only the articles but also the adverts between them.

Let’s assume that our articles will all have a title, as well as many other properties that I won’t list for the sake of simplicity:

class Article {
  var title =  ""
  ...
  init (title:String) {
    self.title = title
  }
}

Let’s also assume that our adverts will all have a description:

class Advertising {
  var description = ""
  ...
  init(description:String)
  {
    self.description = description
  }
}

Now, we need an array which will host instances of both Article and Advertising type. Since Swift arrays are typed we have to base our array on an enum that has associated values to achieve our goal:

enum Content {
  case Story(Article)
  case Ad(Advertising)
}

var articles = [Content]()
var article1 = Article(title: "First article")
var ad1 = Advertising(description: "Some advertising")
var article2 = Article(title: "Second article")

articles += [Content.Story(article1), Content.Ad(ad1), Content.Story(article2)]

So, what’s the problem?

Well, sometimes we have to have a peak at what’s in the array and when we try to do so we usually get a very obscured output:

println(articles)
>>  [(Enum Value), (Enum Value), (Enum Value)]

OK, what can I do about it?

Here’s where the Printable protocol comes into play. Let’s look at what we have to do to get it implemented:

/// A type with a customized textual representation.
///
/// This textual representation is used when objects are written to an
/// *output stream*, for example, by `print` and `println`.
protocol Printable {

  /// A textual representation of `self`.
  var description: String { get }
}

Pretty easy to understand, huh? Probably one of the easiest protocols (if not the easiest one) in Swift.

Hint: Have a peak at the Apple’s documentation for an example on how to use it with structs: https://developer.apple.com/library/ios/documentation/General/Reference/SwiftStandardLibraryReference/Printable.html

The Solution

Let’s say that we want to display the article’s title and the advertising’s description when we print out the articles array.

To achieve that we have to extend our enum a bit, in a way that it implements the Printable protocol. Here’s one way to do it:

enum Content: Printable {
  case Story(Article)
  case Ad(Advertising)

  var description: String {
    get {
      switch(self){
        case let .Story(article):
          return "\"\(article.title)\""
        case let .Ad(advertising):
          return "\"\(advertising.description)\""
      }
    }
  }
}

Doing so allows us to get what we want – the article’s title and the advertising’s description are displayed when we print out the articles array, replacing the obscure (Enum value):

println(articles)
>> ["First article", "Some advertising", "Second article"]

Note: At the moment of writing the Printable protocol doesn’t work in the playground (Xcode 6.1.1), which is a known bug and hopefully will be sorted out soon. The code works great in a project context though 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *