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
Normally the standard types play nice between Objective-C and Swift. But
Bools are an unusual case that require a non-obvious solution.
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.
Did you like this tip? The next tip on speeding up iOS UI code reviews by including screenshot or video diffs is already waiting for you. Or sign up to get every tip straight to your inbox.
This post originally published at Apps Dissected.