I have a Swift API that is exposed to Objc using a protocol marked as "@objc". the API is expected to take "Any?", however, when I pass a Bool
looks like the type is erased (only if marked with "@objc" ) and looks like internally it creates an objc object with the CoreFoundation __kCFBooleanFalse/True. See simplified example below (also here: SwiftObjcBoolInterop · GitHub):
import Foundation
protocol SwiftProtocol {
func passAnyAround(_ input: Any?)
}
@objc public protocol ObjcProtocol {
func passAnyAround(_ input: Any?)
}
class SwiftClassA: SwiftProtocol {
func passAnyAround(_ input: Any?) {
print("---------------")
dump(input)
let isBool = input is Bool
print(isBool)
let isInt = input is Int
print(isInt)
print(type(of: input))
print("---------------")
}
}
@objc class ObjcClassA: NSObject, ObjcProtocol {
@objc func passAnyAround(_ input: Any?) {
print("---------------")
dump(input)
let isBool = input is Bool
print(isBool)
let isInt = input is Int
print(isInt)
print(type(of: input))
print("---------------")
}
}
let boolValue = false
// retains the Bool type
let swiftA: SwiftProtocol = SwiftClassA()
swiftA.passAnyAround(boolValue)
// This version earases the type
let objcA: ObjcProtocol = ObjcClassA()
objcA.passAnyAround(boolValue)
// version2 (not declaring the object as of type ObjcProtocol) retains the Bool type
let objcB = ObjcClassA()
objcB.passAnyAround(boolValue)
I could relate to why this would be the case due to internal implementation & objc limitations, but to confirm, is this the expected behaviour or bug?
If yes, why is version#2 (not declaring the variable of type explicitly as of type ObjcProtocol) still works?
Regardless, I'd appreciate any recommendations to supporting Objc users and not losing the Bool type (at least for Swift users)
Notice that this is simplified case, I'd still like to retain the Bool
type even if the Bool value is embedded in a Dictionary