# Logging in Swift

# dump

dump prints the contents of an object via reflection (mirroring).

Detailed view of an array:

let names = ["Joe", "Jane", "Jim", "Joyce"]
dump(names)

Prints:

▿ 4 elements
- [0]: Joe
- [1]: Jane
- [2]: Jim
- [3]: Joyce

For a dictionary:

let attributes = ["foo": 10, "bar": 33, "baz": 42]
dump(attributes)

Prints:

▿ 3 key/value pairs
▿ [0]: (2 elements)
- .0: bar
- .1: 33
▿ [1]: (2 elements)
- .0: baz
- .1: 42
▿ [2]: (2 elements)
- .0: foo
- .1: 10

dump is declared as dump(_:name:indent:maxDepth:maxItems:).

The first parameter has no label.

There's other parameters available, like name to set a label for the object being inspected:

dump(attributes, name: "mirroring")

Prints:

▿ mirroring: 3 key/value pairs
▿ [0]: (2 elements)
- .0: bar
- .1: 33
▿ [1]: (2 elements)
- .0: baz
- .1: 42
▿ [2]: (2 elements)
- .0: foo
- .1: 10

You can also choose to print only a certain number of items with maxItems:, to parse the object up to a certain depth with maxDepth:, and to change the indentation of printed objects with indent:.

# Debug Print

Debug Print shows the instance representation that is most suitable for debugging.

print("Hello")
debugPrint("Hello")

let dict = ["foo": 1, "bar": 2]

print(dict)
debugPrint(dict)


Yields

>>> Hello
>>> "Hello"
>>> [foo: 1, bar: 2]
>>> ["foo": 1, "bar": 2]


This extra information can be very important, for example:

let wordArray = ["foo", "bar", "food, bars"]

print(wordArray)
debugPrint(wordArray)

Yields

>>> [foo, bar, food, bars]
>>> ["foo", "bar", "food, bars"]


Notice how in the first output it appears that there are 4 elements in the array as opposed to 3. For reasons like this, it is preferable when debugging to use debugPrint

# Updating a classes debug and print values

struct Foo: Printable, DebugPrintable {
    var description: String {return "Clear description of the object"}
    var debugDescription: String {return "Helpful message for debugging"}
}

var foo = Foo()

print(foo)
debugPrint(foo)

>>> Clear description of the object
>>> Helpful message for debugging

Many of us start debugging with simple print(). Let's say we have such a class:

class Abc {
    let a = "aa"
    let b = "bb"
}

and we have an instance of Abc as so:

let abc = Abc()

When we run the print() on the variable, the output is

App.Abc

while dump() outputs

App.Abc #0
- a: "aa"
- b: "bb"

As seen, dump() outputs the whole class hierarchy, while print() simply outputs the class name.

Therefore, dump() is especially useful for UI debugging

let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))

With dump(view) we get:


- <UIView: 0x108a0cde0; frame = (0 0; 100 100); layer = <CALayer: 0x159340cb0>> #0
    - super: UIResponder
      - NSObject 

While print(view) we get:

<UIView: 0x108a0cde0; frame = (0 0; 100 100); layer = <CALayer: 0x159340cb0>>

There is more info on the class with dump(), and so it is more useful in debugging the class itself.

In swift we can use both print() and NSLog() functions to print something on Xcode console.

But there are lot of differences in print() and NSLog() functions, such as:

1 TimeStamp: NSLog() will print timestamp along with the string we passed to it, but print() will not print timestamp.
e.g.

let array = [1, 2, 3, 4, 5]
print(array)
NSLog(array.description)

Output:

[1, 2, 3, 4, 5]
2017-05-31 13:14:38.582 ProjetName[2286:7473287] [1, 2, 3, 4, 5]

It'll also print ProjectName along with timestamp.

2 Only String: NSLog() only takes String as an input, but print() can print any type of input passed to it.
e.g.

let array = [1, 2, 3, 4, 5]
print(array) //prints [1, 2, 3, 4, 5]
NSLog(array) //error: Cannot convert value of type [Int] to expected argument type 'String'

3 Performance: NSLog() function is very slow compare to print() function.

4 Synchronization: NSLog() handles simultaneous usage from multi-threading environment and prints output without overlapping it. But print() will not handle such cases and jumbles while prating output.

5 Device Console: NSLog() outputs on device console also, we can see this output by connecting our device to Xcode. print() will not print output to device's console.

# Remarks

println and debugPrintln where removed in Swift 2.0.

Sources:

https://developer.apple.com/library/content/technotes/tn2347/_index.html (opens new window) http://ericasadun.com/2015/05/22/swift-logging/ (opens new window)

http://www.dotnetperls.com/print-swift (opens new window)