Search code examples
iosswiftcustomstringconvertible

Why does CustomStringConvertible not work for Data?


I have the following:

extension Data : CustomStringConvertible {
    var description : String {
        return base64EncodedString()
    }
}

This shows a warning:

Conformance of 'Data' to protocol 'CustomStringConvertible' was already stated in the type's module 'Foundation'

And because of this warning, Data isn't printed using the description.

Is this not supported?


Solution

  • As Claus Jørgensen's answer says, you cannot "override" the protocol witness description in your own extension.

    If the whole purpose of doing this is just so you can directly print the data, there is an alternative.

    You see, print doesn't just use CustomStringConvertible.description to print values. print just uses String.init(describing:) to work out what string to print, and String.init(describing:) would first check if the value conforms to TextOutputStreamable, before it checks for CustomStringConvertible conformance.

    Luckily, Data doesn't conform to TextOutputStreamable, so you can write

    extension Data : @retroactive TextOutputStreamable {
        public func write<Target>(to target: inout Target) where Target : TextOutputStream {
            target.write(base64EncodedString())
        }
    }
    

    That said, this would be a problem when in some future version Data does conform to TextOutputStreamable. Therefore, the best thing to do is to bite the bullet and explicitly write data.base64EncodedString() in your print calls.