Swift: get the compile time name of variable (referencing to a class)
No, there is no way to do that.
You have to understand that in the compiled state that variable usually does not exist. It can be optimized out or it is represented only as an item on the execution stack.
Even in languages with much better reflection that Swift has, usually you cannot inspect local variables.
To be honest, getting the name of a local variable dynamically has no practical use case.
Get a Swift Variable's Actual Name as String
As per the updated from this answer, it is supported in Swift 3 via #keyPath
NSPredicate(format: "%K == %@", #keyPath(Person.firstName), "Andrew")
Swift. Refer to instance variables by string name
Not Swift-ish, as it's bypassing compile time type checking. Best option is to keep them all in a dictionary, and use a protocol to define allowed data types in the dictionary, but even that is rather poor
Finding all references of a variable or a method in Xcode4
Find in project, though if you are searching to change the name everywhere, better would be to use the Refactoring menu.
EDIT: You can use Refactoring to find where a specific variable is referenced. Select the variable and choose Edit->Refactor->Rename. In the refactoring screen, rename the variable (just add _ at the end or something) and click preview. it will show everywhere in the project that variable is referenced. Click on each file to see the lines where the variable is called. After you're done just cancel the refactor.
Get a Swift class's property name as a String
If you are ok with making your properties @objc you can get the property name like so:
class Person {
@objc var firstName: String
var lastName: String
var downloading: Bool
func excludePropertiesFromCloud() -> [String] {
return [#keyPath(firstName)]
}
}
How can I tell what the class of an instance variable is in Swift
Use type.self
to return a type that can be passed into a method that accepts a type-level argument. For example, UILabel.self
can be passed to the isKindOfClass
method call. The string representation of the class can be found via dynamicType.description()
:
var label = UILabel()
println(label.dynamicType.description())
println(label.isKindOfClass(UILabel.self))
Swift-3
var label = UILabel()
println(type(of: label).description())
Output
UILabel
true
Here's a bit more background -- there are two expressions to be aware of: the postfix self expression and the dynamic type expression. From the docs:
Postfix Self
A postfix self expression consists of an expression or the name of a
type, immediately followed by .self. It has the following forms:expression.self
type.self
The first form evaluates to the value of the expression. For example,
x.self evaluates to x.The second form evaluates to the value of the type. Use this form to
access a type as a value. For example, because SomeClass.self
evaluates to the SomeClass type itself, you can pass it to a function
or method that accepts a type-level argument
Dyamic Type Expression
A dynamicType expression consists of an expression, immediately
followed by .dynamicType. It has the following form:expression.dynamicType
The expression can’t be the name of a type. The entire dynamicType
expression evaluates to the value of the runtime type of the
expression.
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.
Related Topics
Siblings Relationship Between Same Models in Vapor
Avaudiopcmbuffer Built Programmatically, Not Playing Back in Stereo
How to Detect Touches on UIimageview of UItableviewcell in Swift
Leaving Equal Width Gap Spacing Before and Between Menu Buttons
Swiftui Previews - Unexpected Data
Swiftui Multiple Animations for Same Element
Occasional Blank Frames After Exporting Asset - Avexportsession
Uibutton Background Color Overlaps Text on Highlight
How to Refer to a Global Type from Within a Class That Has a Nested Type with The Same Name
Arkit/Scenekit on iOS 14 Throws New Warning (Metal)
Why Swift Disallows Weak Reference for Non-Optional Type
#If Canimport(Coreimage) Not Working in Swift Package Manager
I Opened My App in Xcode 10 and Now I Have Errors in 9.4.1: Sdkapplicationdelegate (Facebookcore)
Weird Toolbar with Nested Conditionals Behavior
Proper Way of Editing a Cocoapod Library