You can use the NS_REFINED_FOR_SWIFT macro to provide a unified interface between Objective-C and Swift, with throws in Swift and NSError ** in Objective-C.
From the Apple Documentation :
You can use the NS_REFINED_FOR_SWIFT macro in the declaration of the Objective-C method to provide an advanced Swift interface in the extension, while keeping the original implementation accessible from the advanced interface. For example, an Objective-C method that takes one or more pointer arguments can be refined in Swift to return a tuple of values.
In your case, you can declare foo as refined for Swift and add the same method to the class extension:
@interface MyClass : NSObject - (void)foo:(void (^)(NSError **))block NS_REFINED_FOR_SWIFT; @end
and in Swift:
extension MyClass { func foo(block: @escaping () throws -> Void) { // Objective-C `foo` is now imported as `__foo` __foo { errPtr in do { try block() } catch { errPtr?.pointee = error as NSError } } } }
Now you can call foo from both worlds, with the difference that Objective-C code must pass an NSError ** block, while Swift subscribers can get a throws close.
source share