'Is it possible to distinguish Bool and Int in Swift?

I have an AnyObject type that can be String, Int or Bool type. I need to distinguish them.

This code tries to do so, but it considers Bool to be Int:

import Cocoa

var value: AnyObject

func checkType(value: AnyObject) -> String {
    if let intvalue: Int = value as? Int {
        return("It is an integer")
    } else if let boolvalue: Bool = value as? Bool {
        return("It is an boolean")
    } else if let stringvalue: String = value as? String {
        return("It is an string")
    }
    return "not found"
}

value = "hello"
checkType(value) // It is an string

value = 1
checkType(value) // It is an integer

value = true
checkType(value) // It is an integer


Solution 1:[1]

func checkType<T>(value: T) -> String {
    var statusText = "not found"
    if value is Int {
        statusText = "It is an integer"
    } else if value is Bool {
        statusText = "It is an boolean"
    } else if value is String {
        statusText = "It is an string"
    }
    return statusText
}

AnyObject cannot be implicitly downcast to any type in Swift. For such case you can use Generics instead.

Generic code enables you to write flexible, reusable functions and types that can work with any type, subject to requirements that you define. Read more.

Solution 2:[2]

The way worked with me is by using the Mirror struct.

let value: Any? = 867
let stringMirror = Mirror(reflecting: value!)
let type = stringMirror.subjectType
print(stringMirror.subjectType)

if type == Bool.self {
    print("type is Bool")
} else if type == String.self {
    print("type is string")
} else if type == Int.self {
    print("type is Int")
}

use Any here since Int, String, Bool are structs. if you just try to distinguish between classes using is should work.

if value is NSString {
    print("type is NSString")
}

Solution 3:[3]

To distinguish Bool from Int (in pure Swift and ObjC bridging) one can use the following extension for AnyHashable

extension AnyHashable {

    var isBool: Bool {
        Bool(description) != nil && !(self is String)
    }

    var boolValue: Bool? {
        isBool ? (self as? Bool) : nil
    }
}

Here we check description which is true/false for Bool-like value and then exclude the same String-like value.

It is common case to get data collection (e.g. json) and cast it as AnyHashable.

The same works for NSNumber.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 M.Othman
Solution 2 M.Othman
Solution 3 malex