How to Change the Textual Representation Displayed For a Type in Swift

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

Swift 2 - 4

Summary

Conform to the CustomStringConvertible protocol and add description:

var description: String {
return "description here"
}

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:

Sample Image

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:

Sample Image

For this reason, the docs say:

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

Change what print(Object) displays in Swift 2.0

It isn't enough to just add a description variable. You need to also state that your class conforms to CustomStringConvertible (formerly known as Printable in earlier Swift versions).

If you command click the print function, you find the following description.

Writes the textual representation of value, and an optional newline,
into the standard output.

The textual representation is obtained from the value using its protocol
conformances, in the following order of preference: Streamable,
CustomStringConvertible, CustomDebugStringConvertible. If none of
these conformances are found, a default text representation is constructed
in an implementation-defined way, based on the type kind and structure.

The part of which that matters here being that objects passed to print are not checked for whether or not they have a description method, but instead checked for things like whether or not the conform to protocols like CustomStringConvertible which offer data to be printed.

That being said, all you need to do in this case is specify that your class conforms to CustomStringConvertible since you've already added a description variable. If you hadn't already added this, the compiler would complain because this protocol requires that the description variable be implemented.

class Digit: CustomStringConvertible {
var num: Int
var x: Int
var y: Int
var box: Int
var hintList: [Int] = []
var guess: Bool = false

var description: String {
let string = String(num)
return string
}
}

swift default string interpolation for object

The property description you have seen belongs to the protocol CustomStringConvertible and is used when you want to convert an object to a string representation. So all you need to do is to conform to the protocol and description will be used in your tests

struct Blah: CustomStringConvertible {
let value: String

init(_ value: String) {
self.value = value
}

var description: String {
value
}
}

QLThumbnailGenerator saveBestRepresentation wrong content type Swift iOS 13+

The iOS 14 way:

At the top of the file, import UniformTypeIdentifiers. Now change

contentType: "image/jpg"

to

contentType: UTType.jpeg.identifier

Displaying text from an array into text box

Obviously, the offending line of code is:

CharAtt1.stringValue = print("\(randomElement)")

It's got a fair number of issues. The most prudent is that print has a type of (approximately, I'm simplifying) (Any) -> Void. You're calling it, passing it a string ("\(randomElement)"). This will print the string to the console, but it will also return back a () (a.k.a. the empty Tuple, of type Void). As the error message suggests, this can't be assigned to CharAtt1.stringValue, which is expecting a String.

The fix is simple, don't call print:

// If you do want to print it, do it in a separate expression
print("\(randomElement)")
CharAtt1.stringValue = "\(randomElement)"

But there's another issue: "\(randomElement)" is useless. randomElement is already a String. You could just write:

print(randomElement)
CharAtt1.stringValue = randomElement

I'd say that "\(anything)" is kind of anti-pattern. If you need to convert something to a string, I think it's better to do so in a way that's more explicit about the conversion you want. E.g. using String(anything) (if such an initializer exists), or String(describing: anything), or String(reflecting: anything) (depending on your usecase)



Related Topics



Leave a reply



Submit