How to Print the Type or Class of a Variable in Swift

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.

how to get type of a variable in swift

You can check the type of any variable using is keyword.

var a = 0
var b = "demo"
if (a is Int) {
print("It's an Int")
}

if (b is String) {
print("It's a String")
}

To compare any complex type, you can use below method:

if type(of: abc) == type(of: def) {
print("matching type")
} else {
print("something else")
}

How do I get the instantiated type of a class in Swift?

You can use type(of:), e.g.,

public class Fruit {
public func getTypeOfFruit() -> Fruit.Type {
return type(of: self)
}
}

public class Apple: Fruit { }

public class TimApple: Apple { }

var fruit = Fruit()
print(fruit.getTypeOfFruit()) // prints "Fruit"

fruit = Apple()
print(fruit.getTypeOfFruit()) // prints "Apple"

fruit = TimApple()
print(fruit.getTypeOfFruit()) // print "TimApple"

How to determine the type of a variable in Swift

You can get a reference to the type object of a value by using the .dynamicType property. This is equivalent to Python's type() function, and is mentioned in the Swift documentation under Language Reference: Types: Metatype Type.

var intArray = [1, 2, 3]
let typeOfArray = intArray.dynamicType

With this type object, we are able to create a new instance of the same array type.

var newArray = typeOfArray()
newArray.append(5)
newArray.append(6)
println(newArray)
[5, 6]

We can see that this new value is of the same type ([Int]) by attempting to append a float:

newArray.append(1.5)
error: type 'Int' does not conform to protocol 'FloatLiteralConvertible'

If we import Cocoa and use an array literal with mixed types, we can see that an NSArray is created:

import Cocoa

var mixedArray = [1, "2"]
let mixedArrayType = mixedArray.dynamicType

var newArray = mixedArrayType()
var mutableArray = newArray.mutableCopy() as NSMutableArray

mutableArray.addObject(1)
mutableArray.addObject(1.5)
mutableArray.addObject("2")

println(mutableArray)
(1, "1.5", 2)

However, at this point there does not seem to be any general way to generate a string description of a type object, so this may not serve the debugging role that you were asking about.

Types derived from NSObject do have a .description() method, as is used in SiLo's answer,

println(mixedArrayType.description())
__NSArrayI

However this is not present on types such as Swift's built-in arrays.

println(typeOfArray.description())
error: '[Int].Type' does not have a member named 'description'

How do you find out the type of an object (in Swift)?

Swift 3 version:

type(of: yourObject)

How to reference a String variable in a class

It might be not the best solution, but you can achieve this with Pointers, like so:

class Test {

private let strPointer: UnsafeMutablePointer<String>

init(strPointer: UnsafeMutablePointer<String>) {
self.strPointer = strPointer
}

func doStuff() {
print(strPointer.pointee)
}

}

var str = "Initial value"

let test = Test(strPointer: &str)
test.doStuff()
// prints 'Initial value'

str = "Another value"
test.doStuff()
// prints 'Another value'

Swift - How to use a class type as a parameter / variable

First read Metatype Type in the The Swift Programming Language. Once read continue with the answer.

From that you have learnt that you can declare a function parameter's type to be the type of types (you are allowed to go crosseyed), AKA metatype, and can therefore pass a type to a function. Combine that with generics and Swift's type inference and you could declare your function as:

func sortFileArrayByType<T>(fileAttributeKeyString : String,
attributeType : T.Type,
fileURLArray : [URL]
) -> [(url: URL, attribute: T)]
where T : Comparable

This adds the parameter attributeType whose type is the metatype of T where T will be inferred. For example the metatype String.self could be passed and T will be inferred to be String.

The where clause constrains T so that only types which are Comparable are allowed, this is required to enable the function to do sorting. File attributes can be Date, String and NSNumber valued; unfortunately the latter does not conform to Comparable so you need to add an extension to make it, the following will suffice:

extension NSNumber : Comparable
{
public static func <(a : NSNumber, b : NSNumber) -> Bool { return a.compare(b) == .orderedAscending }
public static func ==(a : NSNumber, b : NSNumber) -> Bool { return a.compare(b) == .orderedSame }
}

Within the body of the function you need to declare your array of tuples to have attributes of type T:

var tupleArrayWithURLandAttribute : [(url: URL, attribute: T)] = []

and when you add entries you need to cast the value returned by attributesOfItem to be T:

tupleArrayWithURLandAttribute.append((url: url, attribute: value as! T))

Note the use of as! here, you must match the attribute name and the type of its value correctly in the function call or you will get a runtime abort. Handling this as a soft error, if needed, is left as an exercise.

There are a number of typos etc. in the code you posted, they are left for you to fix, having done that your function should work. A call might look like:

let ans = sortFileArrayByType2(fileAttributeKeyString: "NSFileCreationDate",
attributeType: Date.self,
fileURLArray: urlArray)

and the type of ans in this case will be [(url: URL, attribute: Date)]

HTH

Print passed variable name in funciton parameter argument as string (Swift)

There is no way for printValue func to know that you passed a value named positionX because printValue knows only about a variable named variable.
What you could do is changing the printValue func passing also the variable name as a String. E.g:

func printValue(_ value: Double, _ name: String) {
print("\(name) = \(value)")
}

and call it like:

override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad starts here")
let poisitionX: Double = 5.7
printValue(positionX, "positionX")
}


Related Topics



Leave a reply



Submit