iosswiftnsnumber

Swift check if NSNumber is Double


So I'm trying to check whether NSNumber is Double or Int and I'm wondering if it's even possible.

I was hoping this will work, but it always returns true no matter with which type I'm comparing

var myDouble: Double = 0.0
var myNSNumber: NSNumber = NSNumber(value: myDouble)

if myNSNumber is Double {
    print("NSNumber is Double")
}else {
    print("NSNumber is different type")
}

In kotlin I'm using such Extension for Number which is NSNumber in swift and I want to recreate it in swift

protected operator fun Number.plus(other: Number): Number {
    return when (this) {
        is Long -> this.toLong() + other.toLong()
        is Int -> this.toInt() + other.toInt()
        is Short -> this.toShort() + other.toShort()
        is Byte -> this.toByte() + other.toByte()
        is Double -> this.toDouble() + other.toDouble()
        is Float -> this.toFloat() + other.toFloat()
    }
}

Solution

  • You can get type of the number stored using low-level CoreFoundation API:

    extension NSNumber {
        var type: CFNumberType {
            return CFNumberGetType(self as CFNumber)
        }
    }
    

    And then you can use it.

    Your plus function gonna be something like that:

    extension NSNumber {
        func plus(other: NSNumber) -> NSNumber {
            switch type {
            case .sInt8Type, .charType:
                return NSNumber(value: self.int8Value + other.int8Value)
            case .sInt16Type, .shortType:
                return NSNumber(value: self.int16Value + other.int16Value)
            case .sInt32Type, .longType:
                return NSNumber(value: self.int32Value + other.int32Value)
            case .sInt64Type, .longLongType:
                return NSNumber(value: self.int64Value + other.int64Value)
            case .float32Type, .floatType:
                return NSNumber(value: self.floatValue + other.floatValue)
            case .float64Type, .doubleType:
                return NSNumber(value: self.doubleValue + other.doubleValue)
            case .intType, .cfIndexType, .nsIntegerType:
                return NSNumber(value: self.intValue + other.intValue)
            case .cgFloatType:
                switch MemoryLayout<CGFloat>.size {
                case 4:
                    return NSNumber(value: self.floatValue + other.floatValue)
                default:
                    return NSNumber(value: self.doubleValue + other.doubleValue)
                }
            }
        }
    }