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:
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:
For this reason, the docs say:
Using
CustomStringConvertible
as a generic constraint, or accessing a conforming type'sdescription
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
Get Integer Value from String in Swift
Unwrapping Multiple Optionals in If Statement
Dispatch_Once After the Swift 3 Gcd API Changes
Constant Unassigned Optional Will Not Be Nil by Default
What Is Difference Between Optional and Decodeifpresent When Using Decodable For Json Parsing
Extra Arguments At Positions #11, #12 in Call Swiftui
#Ifdef Replacement in the Swift Language
Swift 3 How to Display a Confirmation Screen Based on Mfmailcomposeresult Email Screen
Real Time Nstask Output to Nstextview With Swift
Swift 2 - Pattern Matching in "If"
How Change Background Color If Using Navigationview in Swiftui
Calling Protocol Default Implementation from Regular Method
Get Associated Value from Enumeration Without Switch/Case
How to Get Mathemical Pi Constant in Swift
"Classname Has No Member Functionname" When Adding Uibutton Target
Passing an Array to a Function With Variable Number of Args in Swift
Why Are Emoji Characters Like 👩👩👧👦 Treated So Strangely in Swift Strings