This is a silly question — or rather, it should be a silly question — but it’s going to bite you sometimes when you integrate Objective-C and Swift code together (*cough* UIKit).
You will try to use what you think is a Bool
from an Objective-C API, and suddenly you’re getting this compile error:
Cannot convert value of type ‘ObjCBool’ to expected argument type ‘Bool’
This is a Boolean value; why can’t I use this @($^ thing as a Bool
?
Normally the standard types play nice between Objective-C and Swift. But Bool
s are an unusual case that require a non-obvious solution.
Objective-C uses BOOL
as the type for Boolean values. In earlier versions of Swift, this was properly bridged to a Bool
. In Swift 3, this changed to a value of type ObjCBool
. When you’re used to the standard types being automatically bridged nicely, it’s jarring when suddenly you have what you think is a Bool
, but it can’t be used like a Bool
anywhere. You get the aforementioned error. It also cannot be cast to a Bool
; that results in a compile-time error as well.
It turns out that there is a property on ObjCBool
instances called boolValue
, which is responsible for producing a Swift Bool
from the ObjCBool
. So, in the example I was having a problem with, accessing a BOOL property on an Objective-C object:
let val = objcObject.aBool // This is of type ObjCBool
let boolVal = objcObject.aBool.boolValue // This is actually a Bool
It’s aggravating when Swift itself isn’t very Swift-like, isn’t it?
If you need to go the other direction, that is thankfully more obvious:
let objectiveCBool = ObjCBool(swiftBoolVal)
Maybe one of these days we will be able to put Objective-C behind us all together. Until then, little workarounds like this are going to be part of the game.
Comments are closed.