Say you have your own custom class:

class MyClass {
  let counter: Int

  init(withCounter: Int) {
          self.counter = withCounter
  }
}

Now, you want it to be convertible to String. One way of doing it is to create an extension to the String class itself like this:

extension String {
  init(_ myClass: MyClass) {
    self = "{ counter: \(myClass.counter) }" 
  }
}

This will let you do:

let str = String(MyClass(withCounter:25)) 
// str is "{ counter: 25 }"

This may seem to be sufficient in many cases, but it does not seem to be truly the Swift way. I realised this when working with testing framework (Nimble) and I realised that having just String extension does not make Nimble to produce correct string descriptions of my class instances when testing. In particular, and you can test it easily in the playground, this will not work as expected:

let str2 = "\(MyClass(withCounter:25))" 
// str2 is "MyClass"

For the string interpolation to work as expected in this case, you would rather have to do this:

let str3 = "\(String(MyClass(withCounter:25)))" 
// str3 is "{ counter: 25 }"

This is not how you want to use string interpolation though.

This blog describes how this is supposed to be done correctly in Swift 1 (still with lots of pain), and here is the updated version for Swift 2.

To summarise, this is how you can extend MyClass:

class MyClass: CustomStringConvertible {
  let counter: Int

  var description: String {
      return "{ counter: \(self.counter) }"
    }

    init(withCounter: Int) {
      self.counter = withCounter
  }
}

Now, the string interpolation should work as expected. You can download the gist playground file here.