Swift ReferenceConvertible and _ObjectiveCBridgeable

Does anyone have any experience working with ReferenceConvertible? I noticed that there isn't a lot of documentation or literature surrounding that protocol (and the even more obscure _ObjectiveCBridgable protocol). A number of types use it: UrlRequest, Data etc. It seems really useful just thinking about how URLRequest and NSURLRequest are somewhat interchangable because of it.

consider this example:

struct Value: ReferenceConvertible {
    func _bridgeToObjectiveC() -> MutableValue {
        return MutableValue(int)
    }

    static func _forceBridgeFromObjectiveC(_ source: MutableValue, result: inout Value?) {
        //Question: What happens here? Not Documented anywhere
    }

    static func _conditionallyBridgeFromObjectiveC(_ source: MutableValue, result: inout Value?) -> Bool {
        return true //Question: What is this function used for? Not documented anywhere
    }

    static func _unconditionallyBridgeFromObjectiveC(_ source: MutableValue?) -> Value {
        return Value(int: source!.int) // Question: Why is the source nil here? This isn't documented anywhere
    }

    typealias ReferenceType = MutableValue

    typealias _ObjectiveCType = MutableValue //Not documented anywhere, is this a correct implementation?

    var description: String { return "" }

    var debugDescription: String { return "" }

    var int: Int

}

class MutableValue: NSObject, NSCopying {
    var int: Int

    init(_ int: Int) {
        self.int = int
    }

    func copy(with zone: NSZone? = nil) -> Any {
        return self // Is this correct?
    }
}

let value = Value(int: 0)
print(value.int)// 0
let mutable = value as MutableValue
mutable.int += 1
let new = mutable as Value
print(new.int)// 1

I guess the underscore that prefixes those functions is trying to tell someone maybe it isn't a good idea to implement these functions. Cause doesn't an underscore traditionally mean private method or method that shouldn't be used normally?

Right. In Swift, a leading underscore usually means “this needs to be public for technical reasons, but it’s really some piece of internal machinery you shouldn’t touch”. That’s especially true for declarations from the standard library or a framework overlay. The generated header in Xcode actually hides these kinds of symbols.

1 Like

Generally speaking, we do not support bridging except on any of the types that currently already have it. Please don't form your own conformances? Things will break. (For example, one of the things that's a leftover from 4.2 is that we want to change the name of that protocol.)

2 Likes

That's fine with me. I was honestly just curious because I didn't understand the connection between URLRequest and MutableURLRequest and why they could be interchangable when one is a struct and the other is a class. I wanted to understand it's purpose. Why doesn't ReferenceConvertible have a leading underscore if it's a private api that has to be public for reasons like _ObjectiveCBridgable? The only reason I discovered _ObjectiveCBridgable was because I first discovered ReferenceConvertible and tried to have a type conform to it and then got a warning that said the type doesn't conform to _ObjectiveCBridgable

Gotcha, thank you. So why doesn't ReferenceConvertible follow that pattern? It was only until I conformed to it that I was told to also conform to _ObjectiveCBridgeable. I won't use it but I just noticed the connection between URLRequest and MutableURLRequest and investigated. Found out some other types conform to ReferenceConvertible and I was just honestly curious about its purpose and uses.