Search code examples
objective-cswiftlanguage-interoperability

how do I bridge a function taking a closure as a parameter to objc


I have

func verifyEmail(let email: String, let completionHandler:(Bool) -> Void) -> Bool
{

in my (swift) framework

exposing it as

FOUNDATION_EXPORT BOOL verifyEmail(NSString *email, void (^completionHandler)(BOOL verificationResult));

in my framework umbrella header

attempting to call it like so

verifyEmail(@"dfs", ^(BOOL verificationResult) {
    NSLog(@"objc: using sdk v%f", whateverSdkVersionNumber);
});

in objective c sample code results in a link error: Undefined symbols for architecture arm64: "_verifyEmail", referenced from: -[ObjCExample verify] in ObjCExample.o ld: symbol(s) not found for architecture arm64

Same with other functions exported but if I can map closures to blocks or whatever I'll surely fix the rest :^)

Resolved: converted globals to class func()s


Solution

  • You cannot access Swift functions declared in global scope in your Objective-C code. Per documentation:

    You’ll have access to anything within a class or protocol that’s marked with the @objc attribute as long as it’s compatible with Objective-C. This excludes Swift-only features such as those listed here:

    • Generics
    • Tuples
    • Enumerations defined in Swift
    • Structures defined in Swift
    • Top-level functions defined in Swift
    • Global variables defined in Swift
    • Typealiases defined in Swift
    • Swift-style variadics
    • Nested types

    Including FOUNDATION_EXPORT ... in your umbrella header exposes only the function's definition, the symbol itself is not ported to Objective-C.