Is there a way to achieve something like `AnyObjCType`?

Hi,

I'm trying to make some reusable code to dynamically bind to ObjC functions (to avoid strong linking frameworks that I want to use only if the app using my framework has also linked them), along the links of this AdSupport workaround:


...but obviously there's a lot of ugly boilerplate in there.

The problem I'm having is trying to hide the currying of IMP, SEL args from the caller because that means you can't avoid the boilerplate of accessing the IMP and SEL.

Here's an example that works only for zero-arg ObjC functions that return Int:

func dynamicBindIntReturn(toInstanceMethod methodName: String, on object: AnyObject) throws -> () -> Int {
    let selector = NSSelectorFromString(methodName)
    guard let method = object.method(for: selector) else {
        throw DynamicBindError.methodNotFound
    }
    typealias funcType = @convention (c) (AnyObject, Selector) -> Int
    let dynamicFunction: funcType = unsafeBitCast(method, to: funcType.self)
    return {
        return dynamicFunction(object, selector)
    }
}

While this approach works, it is very unwieldy for a few reasons, but for the purposes of this post, it cannot be made generic over the return type because there seems to be no way to constrain the return type of a function to only types representatble in ObjC, which causes compile errors on the funcType typealias.

Hence the above has a very specific type. Doing this for every possible ObjC type would be very tiresome.

Is there anything like AnyObjCType or a way to represent such?

Not to my knowledge. And I suppose that NSObject/NSObjectProtocol are not your obvious friends because they would require Int and String to be processed as NSNumber and NSString, aren't they? Yet did you try to see where this goes?

I did investigate this and I don't believe it will work because the bridging of boxed types to scalar types will not happen.

What is particularly annoying about this is that I have a shot at using some generic currying functions (e.g. func curry<A, B, ReturnType>(a: A, b: B) -> (b: B) -> ReturnType) but only if I can constraint the types of those args to C-compatible types.