I just noticed that printing Foundation objects no longer shows their values in Swift 4.2:
let num = NSNumber(value: 123)
print(num)
In Swift 4.1 (Xcode 9.4.1, default toolchain) the output is
123
With Swift 4.2 (Xcode 10 beta 2, default toolchain) I get just
__NSCFNumber
I thought that print() uses the description or debugDescription, but apparently that is not the case (anymore):
let num = NSNumber(value: 123)
print(num) // __NSCFNumber
print(num.description) // 123
print(num.debugDescription) // 123
print("\(num)") // 123
I also thought (from [stdlib] Array.description calls debugDescription on its contents) that printing an array calls debugDescription on each element, but that does not work either:
let a = [NSNumber(value: 123), NSNumber(value: true)]
print(a) // [__NSCFNumber, __NSCFBoolean]
print(a.description) // [__NSCFNumber, __NSCFBoolean]
print(a.debugDescription) // [__NSCFNumber, __NSCFBoolean]
print("\(a)") // [__NSCFNumber, __NSCFBoolean]
Another example: Bridging Data to NSData used to be a workaround to see the contents, since Data.description only shows the number of bytes:
let data = Data(bytes: [1, 2, 3])
print(data) // 3 bytes
// Swift 4.1 (Xcode 9.4.1):
print(data as NSData) // <010203>
// Swift 4.2 (Xcode 10):
print(data as NSData) // Foundation._NSSwiftData
Another (perhaps more realistic) example where the new behavior is inconvenient:
let jsonData = Data("""
{ "number" : 123, "string": "Hello World", "bool" : true }
""".utf8)
let dict = try! JSONSerialization.jsonObject(with: jsonData, options: []) as! [String: Any]
print(dict) // ["number": __NSCFNumber, "string": __NSCFString, "bool": __NSCFBoolean]
print("\(dict)") // ["number": __NSCFNumber, "string": __NSCFString, "bool": __NSCFBoolean]
Is this a known problem, or am I overlooking something? Otherwise I'll file it as a bug.
I am aware that one cannot rely on a certain output when printing objects, but this makes it almost useless even for debugging/logging purposes.