mythz mythz - 3 months ago 13
Swift Question

How can I change the textual representation displayed for a type in Swift?

How can I modify the textual output that gets displayed in string interpolation?


protocol looks the most obvious but it's ignored in both String Interpolation and when printing the instance, e.g:

struct Point : Printable
var x = 0
var y = 0

var description : String {
return "(\(x), \(y))"

func toString() -> String {
return description

Likewise the
convention has no effect either:

var p = Point(x: 10, y: 20)

println(p) // V11lldb_expr_05Point (has 2 children)
println("\(p)") // V11lldb_expr_05Point (has 2 children)
println(p.description) // (10, 20)
println("\(p.description)") // (10, 20)

The behavior is different again in PlayGround which uses its own String representation for structs, i.e:

p // {x 10, y 20}

Is there a way I can change how an instance is displayed?


Swift 2 & 3

In Swift 2, Printable became CustomStringConvertible. For example, you can create some structs:

struct Animal : CustomStringConvertible {
    let type : String

    var description: String {
        return type

struct Farm : CustomStringConvertible {
    let name : String
    let animals : [Animal]

    var description: String {
        return "\(name) is a \(self.dynamicType) with \(animals.count) animal(s)."

If you initialize them:

let oldMajor = Animal(type: "Pig")
let boxer = Animal(type: "Horse")
let muriel = Animal(type: "Goat")

let orwellsFarm = Farm(name: "Animal Farm", animals: [oldMajor, boxer, muriel])

The custom descriptions will appear in your playground:

enter image description here

See also CustomDebugStringConvertible, which you can use for more verbose output during debugging.

Usage Note

You can initialize a String from any type without implementing this protocol. For example:

enter image description here

For this reason, the docs say:

Using CustomStringConvertible as a generic constraint, or accessing a conforming type's description directly, is therefore discouraged.