-1

Title is sub-optimal, suggestions welcome

Ran into a little trouble with Bool and numeric values. I want to determine if an AnyObject (from a JSON) is a Bool or a number.

So I need a test that will only succeed if the inserted type was truly a Bool or a number. Now it automatically converts and all statements are true.

let some : AnyObject = 1

if some is Bool {
    print("is Bool", some as! Bool)
}

if some is Int {
    print("is Int", some as! Int)
}

let some2 : AnyObject = false

if some2 is Bool {
    print("is Bool", some2 as! Bool)
}

if some2 is Int {
    print("is Int", some2 as! Int)
}

let some3 : AnyObject = 1.1

if some3 is Bool {
    print("is Bool", some3 as! Bool)
}

if some3 is Int {
    print("is Int", some3 as! Int)
}
R Menke
  • 8,183
  • 4
  • 35
  • 63

1 Answers1

1

1, 1.0, true, all types are bridged to NSNumber

You can check the objCType

let some : AnyObject = true

if let type = String.fromCString(some.objCType) {
  switch type {
  case "c" : print("is Bool", some as! Bool)
  case "q" : print("is Int", some as! Int)
  case "d" : print("is Double", some as! Double)
  default :  print("no idea")
  }
} else {
  print("no matching objCType")
}

Source: Type Encodings

vadian
  • 274,689
  • 30
  • 353
  • 361
  • Perfect, I feared there was no way to do this. – R Menke Jun 02 '16 at 17:02
  • Just because you **can** doesn't mean you **should**. You'd be better off reworking this to use Generics, or at least `Any`. (Unlike `AnyObject`, primitives can be used with `Any` without bridging to NSNumber) – Alexander Jun 02 '16 at 17:03
  • @AMomchilov well I don't believe my experiments with JSON -> Swift Model with have far reaching real world effects..... – R Menke Jun 02 '16 at 17:04
  • 4
    This will detect `NSNumber(char: 65)` as a boolean ... – Martin R Jun 02 '16 at 17:04
  • I'm not saying they will, but this is just bad stuff to base your learning off anyway. You're bridging from Swift to Objective C, bridging to C to get a C string, then converting it back into a Swift String just to switch on it to do forced casting. This is gross. – Alexander Jun 02 '16 at 17:06
  • 2
    I haven't done much testing, but this *seems* to work better: http://stackoverflow.com/a/30223989/1187415. – Martin R Jun 02 '16 at 17:06
  • 2
    @MartinR Yes, of course, but I guess the purpose of the question is to get the numeric type out of JSON – vadian Jun 02 '16 at 17:06
  • @vadian that is true, the code above a just a mock – R Menke Jun 02 '16 at 17:07
  • 1
    @MartinR Yes, much better, but even still, this problem should be addressed at the root cause. This wouldn't be necessary if the source of the `AnyObject` was designed properly. – Alexander Jun 02 '16 at 17:10
  • 2
    @AMomchilov show me a way to receive data from a remote source as native Swift types and I will take it! – R Menke Jun 02 '16 at 17:12
  • 1
    On 32-bit platforms, `Int` would be encoded as "i", not "q". – Martin R Jun 02 '16 at 17:30
  • @MartinR All my tests just passed, thank you! – R Menke Jun 02 '16 at 17:35