0

I've an objective-c function that looks like below

+ (void) invokeSortingWithClassName: (NSString*) className functionName: (NSString*) functionName closure: (id(^)(NSArray* arr))closure;

and I've to call this method from a swift class. The swift code that calls this method looks like below

SortHandler.invokeSorting(withClassName: className, functionName: functionName, closure:
{
    args in 
    let something = unwrap(args!)
    do
    {
        let returnValue = try closure(something as NSArray!) //this is another closure coming as a parameter in the function in which this code is written and this throws
        return returnValue;
    }
    catch
    {
        throw error

    }
    return "-1" as! T
})

At the start of closure definition, I get this attached error enter image description here

Essentially, this closure throws an error and I am not sure, how to handle this error in objective-c definition of this function. Please help me fix this error

prabodhprakash
  • 3,825
  • 24
  • 48
  • 2
    Your closure can't throw an error. You will need to resort to simply returning `nil` to indicate failure or even causing a runtime exception depending on how severe the problem is. Also a return after a throw makes no sense. – Paulw11 Mar 30 '17 at 06:29
  • Why cannot a closure throw an error? Is there any Apple document supporting it or link to any other blog/SO post? – prabodhprakash Mar 30 '17 at 06:42
  • 1
    *A closure* can throw, but *this closure* cannot; it is not declared to throw (which is what the error message is telling you) and it can't be declared to throw since it is declared in an Objective-C class and Objective-C knows nothing of Swift exceptions. – Paulw11 Mar 30 '17 at 06:46
  • 1
    Exactly this is my question - how can I declare the same in objective-c? Is there a way to do it? – prabodhprakash Mar 30 '17 at 06:47
  • There is a way to handle it: https://www.uraimo.com/2015/11/03/error-handling-from-objective-c-to-swift-2-and-back/ - but, I am not able to solve it for closures. – prabodhprakash Mar 30 '17 at 06:48

1 Answers1

3

While a closure can be declared with throws, this closure has not been declared with throws, so your closure cannot throw - this is exactly what the error message is telling you.

Since the function is declared in Objective-C, the function signature can't be changed to include throws as Objective-C doesn't know anything about Swift exceptions.

The standard way in which error handling is translated between Swift and Objective-C is for the Objective-C block to receive an &NSError parameter.

If you have the ability to change the Objective-C method signature, it should be declared as

+(void) invokeSortingWithClassName: (NSString* _Nullable) className functionName: (NSString* _Nullable) functionName closure: (id _Nullable (^_Nullable)(NSArray* _Nullable arr, NSError* _Nullable * _Nullable error))closure;

This will allow you to throw from swift with the error being received via the error parameter in Objctive-C.

If you cannot change the method signature, then you will need to catch the exception in your closure and simply return an 'error' value, such as nil

Paulw11
  • 108,386
  • 14
  • 159
  • 186