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
}
}
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.
Selecting global or object print function
Indeed, NSView
has a
func print(_ sender: AnyObject?)
method to open the Print panel, which is an unfortunate conincidence.
Your myPrint()
wrapper has some limitations, for example
myPrint("b", appendNewline : false)
does not compile. A better implementation would be
func myPrint<T>(o : T, appendNewline nl: Bool = true) {
print(o, appendNewline: nl)
}
But you can simply prepend the module name "Swift" to refer to the global function explicitly:
Swift.print("xxx")
Populate List in Swift 2.0 and display results
Your basic intuition is correct, it's better to have an array of custom objects, not multiple arrays.
Regarding making it more Swifty, consider your Users
type. You might want something like:
struct User {
let username: String
let userId: String
let following: Bool
}
Note,
- property names should start with lowercase letter;
Users
should probably be calledUser
, as it represents a single user;- we don't generally initialize values to default values like that, but rather specify them in the initializer;
- we probably use
String
notNSString
; - if a property cannot change, you'd use
let
, notvar
; - properties begin with lower case letters;
Then you can do something like:
var t = [User]()
for object in users {
if let o = object as? PFUser {
t.append(User(username: o.username!, userId: o.objectId!, following: o.IsFollowing!)
}
}
print(t)
Clearly, with all of those !
forced unwrapping operators, you'd want to be confident that those fields were populated for all of those properties.
Using struct
is nice because (a) it's a value type; (b) you get the initializer for free; and (c) you can just print them. If you really wanted User
to be a reference type (a class
), you'd do something like:
class User {
let username: String
let userId: String
let following: Bool
init(username: String, userId: String, following: Bool) {
self.username = username
self.userId = userId
self.following = following
}
}
And if you wanted to be able to just print
them, you'd define it to conform to CustomStringConvertible
:
extension User: CustomStringConvertible {
var description: String { return "<User; username = \(username); userId = \(userId); following = \(following)>" }
}
With the class, you can feel free to change that description
computed property to show it in whatever format you want, but it illustrates the idea.
How do I print the type or class of a variable in Swift?
Update September 2016
Swift 3.0: Use type(of:)
, e.g. type(of: someThing)
(since the dynamicType
keyword has been removed)
Update October 2015:
I updated the examples below to the new Swift 2.0 syntax (e.g. println
was replaced with print
, toString()
is now String()
).
From the Xcode 6.3 release notes:
@nschum points out in the comments that the Xcode 6.3 release notes show another way:
Type values now print as the full demangled type name when used with
println or string interpolation.
import Foundation
class PureSwiftClass { }
var myvar0 = NSString() // Objective-C class
var myvar1 = PureSwiftClass()
var myvar2 = 42
var myvar3 = "Hans"
print( "String(myvar0.dynamicType) -> \(myvar0.dynamicType)")
print( "String(myvar1.dynamicType) -> \(myvar1.dynamicType)")
print( "String(myvar2.dynamicType) -> \(myvar2.dynamicType)")
print( "String(myvar3.dynamicType) -> \(myvar3.dynamicType)")
print( "String(Int.self) -> \(Int.self)")
print( "String((Int?).self -> \((Int?).self)")
print( "String(NSString.self) -> \(NSString.self)")
print( "String(Array<String>.self) -> \(Array<String>.self)")
Which outputs:
String(myvar0.dynamicType) -> __NSCFConstantString
String(myvar1.dynamicType) -> PureSwiftClass
String(myvar2.dynamicType) -> Int
String(myvar3.dynamicType) -> String
String(Int.self) -> Int
String((Int?).self -> Optional<Int>
String(NSString.self) -> NSString
String(Array<String>.self) -> Array<String>
Update for Xcode 6.3:
You can use the _stdlib_getDemangledTypeName()
:
print( "TypeName0 = \(_stdlib_getDemangledTypeName(myvar0))")
print( "TypeName1 = \(_stdlib_getDemangledTypeName(myvar1))")
print( "TypeName2 = \(_stdlib_getDemangledTypeName(myvar2))")
print( "TypeName3 = \(_stdlib_getDemangledTypeName(myvar3))")
and get this as output:
TypeName0 = NSString
TypeName1 = __lldb_expr_26.PureSwiftClass
TypeName2 = Swift.Int
TypeName3 = Swift.String
Original answer:
Prior to Xcode 6.3 _stdlib_getTypeName
got the mangled type name of a variable. Ewan Swick's blog entry helps to decipher these strings:
e.g. _TtSi
stands for Swift's internal Int
type.
Mike Ash has a great blog entry covering the same topic.
Printing Parse Class into UILabel (SWIFT)
Yes. Let's say your Parse object has a value for key objectDescription
which is a string.
You would call a objectForKey
method on this object to get the value and show it in a label.
yourLabel.text = yourParseObject.objectForKey("objectDescription") as? String
print without newline in swift
Starting in Swift 2.0, the recommended method of printing without newline is:
print("Hello", terminator: "")
Remove println() for release version iOS Swift
As noted, i am a student and need things defined a little more clearly to follow along. After lots of research, the sequence I needed to follow is:
Click on the project name at the top of the File Navigator at the left of the Xcode project window. This is line that has the name of the project, how many build targets there are, and the iOS SDK version.
Choose the Build Settings tab and scroll down to the "Swift Compiler - Custom Flags" section near the bottom. Click the Down Arrow next to Other Flags to expand the section.
Click on the Debug line to select it. Place your mouse cursor over the right side of the line and double-click. A list view will appear. Click the + button at the lower left of the list view to add a value. A text field will become active.
In the text field, enter the text -D DEBUG
and press Return to commit the line.
Add a new Swift file to your project. You are going to want to make a custom class for the file, so enter text along the lines of the following:
class Log {
var intFor : Int
init() {
intFor = 42
}
func DLog(message: String, function: String = __FUNCTION__) {
#if DEBUG
println("\(function): \(message)")
#endif
}
}
I was having trouble getting the class to be accepted by Xcode today, so the init may be a bit more heavyweight than necessary.
Now you will need to reference your custom class in any class in which you intend to use the new custom function in place of println()
Add this as a property in every applicable class:
let logFor = Log()
Now you can replace any instances of println()
with logFor.DLog()
. The output also includes the name of the function in which the line was called.
Note that inside class functions I couldn't call the function unless I made a copy of the function as a class function in that class, and println()
is also a bit more flexible with the input, so I couldn't use this in every instance in my code.
How do you find out the type of an object (in Swift)?
Swift 3 version:
type(of: yourObject)
Related Topics
How to Find the Index of an Item in Swift
Facebookshare Causing Compiler Error After Update
Scrollbar Incorrectly Appears Underneath Uicollectionview Section Header
Generating Random Values in Swift Between Two Integer Values
How to Check for 'Nil' in While Loop Condition in Swift
How to Use Swift Flatmap to Filter Out Optionals from an Array
How to Share Both Image and Text Together in Swift
Swift Delegate for a Generic Class
How to Get the Centre of the View
Can't Create an Array of Types Conforming to a Protocol in Swift
Wcsession Has Not Been Activated
Where to Get Frame Size of Custom Uiview in Its Subclass
Cut a Circle Out of a Uiview Using Mask
How Are the Arkit People Occlusion Samples Being Done
How to Check If an Email Address Is Already in Use Firebase
Convert Screen Coordinates to Metal's Normalized Device Coordinates
Class Level or Struct Level Method in Swift Like Static Method in Java