Objective-C Closure to use Swift enum

Viewed 563

I've got Swift enum like this:

@objc public enum Status: Int {

    case unknown;
    case ok;
    case failed;
}

It's properly bridged to Objective-C, and I can use it as, say StatusUnknown in Objective-C.

Now I have a function with callback:

+ (void)fetch:(void (^_Nonnull)(BOOL success))completion 

And all I want is to replace BOOL with my Status enum. How to do that?

Clearly not like this:

+ (void)fetch:(void (^_Nonnull)(Status success))completion // Error: Unknown type name

I could use NSInteger like this:

+ (void)fetch:(void (^_Nonnull)(NSInteger success))completion

but then it's not really limiting values to Status enum.

So what is the best way to convey enum here?

Note:

  • I simplified question, in reality enum is not called status and has many more values.
  • Signature of the function has to match previous signature, but with different argument
1 Answers

To be compatible with objective-c enum must be inherited from Int, like

@objc public enum Status: Int {
    case unknown
    case ok
    case failed
}

make sure generated bridge header file "YOURPROJECT-Swift.h" contains

typedef SWIFT_ENUM(NSInteger, Status, closed) {
  StatusUnknown = 0,
  StatusOk = 1,
  StatusFailed = 2,
};

then in your .m file

#import "YOURPROJECT-Swift.h"

...

+ (void)fetch:(void (^_Nonnull)(Status success))completion
{
    // do anything needed    
}

Clean/Build - all compiled well. Tested with Xcode 11.2.

Related