Quick try inside Objective-C block

I need to create a function foo that takes a throw close as a parameter. I can implement it using Swift or ObjC, but I need to be able to call it from both.

Like this:

 // Swift func bar() throws func foo(_ block: () throws -> void) foo { try bar() } 

and

 // Objc [self foo:^( [other barBar]; )]; 

I tried to implement it with both Swift and ObjC without succes. With Swift:

 @objc func foo(block: () throws -> Void) 

I get this error:

The method cannot be marked as @objc because parameter type 1 cannot be represented in Objective-C

If I try to implement it using ObjC:

 typedef BOOL (^ThrowingBlock)(NSError **); - (void)foo:(ThrowingBlock)block; 

Then it does not translate the block that throws ( as it would with a function ):

 func foo(_: (NSErrorPointer) -> Bool) 

Any idea how to achieve this?

+5
source share
1 answer

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.

+2
source

Source: https://habr.com/ru/post/1275922/


All Articles