Swift: Get The Compile Time Name of Variable (Referencing to a Class)

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



Leave a reply



Submit