I created an objective-c method which will invoke a method via NSInvocation:
typedef void (^ScriptingEmptyBlock)();
typedef void (^ScriptingErrorBlock)(NSErr
I must admit that I don't fully understand why this is happening, but as far as I can tell this has nothing to do with using NSInvocation
and would happen even if we just passed a Swift closure to an Objective-C function via a parameter of type id
. Passing an Objective-C block via id
works just fine, not sure why: Swift closures are supposed to be compatible with Objective-C blocks. As you know, elements of NSArray
are of type id
, so any Objective-C object can be an array element.
To work around this problem of accessing a Swift closure passed via id
in Objective-C one can introduce a wrapper class.
// In a header:
@interface EmptyBlockWrapper : NSObject
@property EmptyBlock _blk;
@end
// In an implementation file (just an empty implementation):
@implementation EmptyBlockWrapper
@end
Then we can use a wrapper instance instead of a block as an array element in Swift:
let myBlock : EmptyBlock = {
print("In Swift EmptyBlock...")
}
let myBlockWrapper = EmptyBlockWrapper()
myBlockWrapper._blk = myBlock
In an Objective-C method we can call it as follows, assuming args
is NSArray *
:
EmptyBlockWrapper * emptyBlockWrapper = args[1];
emptyBlockWrapper._blk();
Hopefully this is helpful. Of course, this is just a simplified example to give you an idea; this could be made much fancier.