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'
Checking if an object is a given type in Swift
If you want to check against a specific type you can do the following:
if let stringArray = obj as? [String] {
// obj is a string array. Do something with stringArray
}
else {
// obj is not a string array
}
You can use "as!" and that will throw a runtime error if obj
is not of type [String]
let stringArray = obj as! [String]
You can also check one element at a time:
let items : [Any] = ["Hello", "World"]
for obj in items {
if let str = obj as? String {
// obj is a String. Do something with str
}
else {
// obj is not a String
}
}
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 to observe a variable from another variable?
As mentioned in the comments, you can make your array a computed property. That resulting array will be what you display in ForEach
.
See inline comments for explanations.
class Clients: ObservableObject {
@Published var items : [ClientItem] = [
.init(id: "1", name: "Z", phone: "1", email: "c"),
.init(id: "2", name: "Y", phone: "2", email: "b"),
.init(id: "3", name: "X", phone: "3", email: "a", isVisited: true)
]
enum FilterType {
case none, id, name, visited, notVisited
}
@Published var filterType : FilterType = .none //what type of filter is active
var itemsOrderedByName: [ClientItem] {
items.sorted { (client1, client2) -> Bool in
let client1 = client1.name
let client2 = client2.name
return (client1.localizedCaseInsensitiveCompare(client2) == .orderedAscending)
}
}
var itemsOrderedById: [ClientItem] {
items.sorted { (client1, client2) -> Bool in
let client1 = client1.id
let client2 = client2.id
return (client1.localizedCaseInsensitiveCompare(client2) == .orderedAscending)
}
}
var itemsVisited: [ClientItem] {
items.filter { item in
return item.isVisited == true
}
}
var itemsNotVisited: [ClientItem] {
items.filter { item in
return item.isVisited == false
}
}
var filteredItems : [ClientItem] { //return an array based on the current filter type
switch filterType {
case .none:
return items
case .id:
return itemsOrderedById
case .name:
return itemsOrderedByName
case .visited:
return itemsVisited
case .notVisited:
return itemsNotVisited
}
}
}
struct ContentView: View {
@StateObject var clients = Clients()
@State private var showAddClient = false
@State private var showFilterSheet = false
var body: some View {
NavigationView {
List {
ForEach(clients.filteredItems) { item in //iterate over the filtered elements
HStack {
VStack(alignment: .leading) {
Text(item.name).font(.headline)
Text(item.id)
Text(item.isVisited ? "Visited" : "Not visited")
}
Spacer()
VStack(alignment: .trailing) {
Link(item.phone, destination: URL(string: "tel:\(item.phone)")!)
Text(item.email)
}
}
}
.onDelete(perform: removeItems)
}
.navigationTitle("Dummy")
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button("Filter") {
showFilterSheet = true
}
.confirmationDialog("Select filter", isPresented: $showFilterSheet) {
Button("ID") {
clients.filterType = .id //set the filter type (same for the other types of buttons)
}
Button("Name") {
clients.filterType = .name
}
Button("Visited") {
clients.filterType = .visited
}
Button("No visitados") {
clients.filterType = .notVisited
}
Button("Cancel", role: .cancel) {
clients.filterType = .none
}
} message: {
Text("Filter by")
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button {
showAddClient = true
} label: {
Image(systemName: "plus")
}
}
}
}
}
func removeItems(at offsets: IndexSet) {
//we can't just use the index any more, because of the filter. So, find the corresponding item based on the current filter and then delete the item from the original array with a matching id
if let offset = offsets.first {
let item = clients.filteredItems[offset]
clients.items.removeAll { $0.id == item.id }
}
}
}
how to check the type of a variable in swift
You can do this with the is
operator.
Example code:
var test: AnyObject
test = 12.2
if test is Double {
println("Double type")
} else if test is Int {
println("Int type")
} else if test is Float {
println("Float type")
} else {
println("Unkown type")
}
According to Apple docs:
Checking Type
Use the type check operator (is) to check whether an instance is of a certain subclass type. The type check operator returns true if
the instance is of that subclass type and false if it is not.
How do you find out the type of an object (in Swift)?
Swift 3 version:
type(of: yourObject)
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 can you quickly view a variable type in Xcode and Swift?
Alt-click
on the variable does the thing in my case most of the time.
Swift variable comparison where type is not known
Expanding on the comments already made to the question: You should make
the class generic, so that it can be used with String
or Int
items. What you need is that the items can be compared with ==
,
i.e. that the type is Equatable
.
The class declaration would then be
public class SearchOption<T : Equatable> {
// ...
}
and all occurrences of AnyObject
have to be replaced by T
.
The isSelected
method simplifies to
public func isSelected(selectedOption: T) -> Bool {
if self.selectedOption != nil {
return self.selectedOption!.contains( { $0 == selectedOption })
}
return false
}
which can be further simplified using optional chaining
and the nil-coalescing operator ??
:
public func isSelected(selectedOption: T) -> Bool {
return self.selectedOption?.contains( { $0 == selectedOption }) ?? false
}
Similarly:
public func removeSelectedItem(selectedOption: T) -> Void {
self.selectedOption = self.selectedOption?.filter( { $0 != selectedOption } )
}
For String
items you would then create an instance of the class
with
let make = SearchOption<String>(title: "Make", allowAny: true, allowMultiple: true, dependencies: nil)
Related Topics
From Any Utf-16 Offset, Find the Corresponding String.Index That Lies on a Character Boundary
Can Not Conform to Protocol by Creating Extension with Where Clauses
Swiftui Tabbar: Action for Tapping Tabitem of Currently Selected Tab to Reset View
How to Add Floating Button on Top of the Uitableview
Swift Create Byte Buffer Holder for Nsstream
Prevent Error "Funk" Sound in Event Monitor Os X
Swiftui MACos Commands (Menu Bar) and View
How to Retrieve All Contacts Using Cncontact.Predicateforcontacts
Is This Safe to Call Wait() of Dispatchsemaphore Several Times at One Time
How to Initialise a New Nsdocument Instance in Swift
App Crashes from IPA File But Runs Fine from Xcode
Swift: Move Uiimage Partly Along Path
Swift Protocol Defining Class Method Returning Self
How to Suppress a Specific Warning in Swift
More Concise Way to Nest Enums for Access by Switch Statements in Swift
Com.Apple.Itunes Aedeterminepermissiontoautomatetarget Is Always Return -600