I have an NSValue object that can "box" an instance of an unknown type (CGPoint, CGRect, etc.) and I need to determine this type in runtime. How would I do it in Swift?
I tried to do something like this:
if ((value as Any) is CGPoint) {}
else if (((value as Any) is CGRect)) {}
...
When value
is a NSValue object containing a CGPoint, it does not get into the if clause.
Then I when I printed value
it gives me NSPoint: {150, 150}
which I assume is why it never gets in the clause.
Any ideas why this happens and how to solve it?
Thanks a lot!
Ah, NSValue
, you so crazy. Even though NSRect
etc aren't supposed to be a thing on iOS, if you put a CGRect
inside an NSValue
, internally it displays it has an NSRect
inside it.
Anyway, while they serve similar purposes I don't think you can use Any
to convert an NSValue
to or from a CGPoint
or CGRect
. You have to call value.CGRectValue()
etc. But to your point, you need to know which it is. Which also isn't easy, but you can do this:
let type = String.fromCString(val.objCType) ?? ""
if type.hasPrefix("{CGRect") {
let rect = val.CGRectValue()
}
else if type.hasPrefix("{CGPoint") {
let point = val.CGPointValue()
} //etc...
But another question would be, do you really need to use NSValue
? It's kind of an Obj-C specific workaround. Is it being given to you by something you can’t change or might you be better off using Any
(or even better, generics) instead?