How to reference Swift enum in Objective-C Header

前端 未结 7 2055
星月不相逢
星月不相逢 2021-01-31 19:38

Is there a way to reference a Swift enum from an Objective-C header? If you want to see Swift classes in the Objective-C header you can use

@objc class Foo


        
相关标签:
7条回答
  • 2021-01-31 19:53

    You can access Swift enums in Objective-C, but only if the enum is declared with an @objc qualifier, which means that it has to be of type Int.

    0 讨论(0)
  • 2021-01-31 20:05

    What you want to do is called forward declaration. To forward declare an enum you can do:

    enum name;
    

    But since the compiler won't know the size of the enum, you will only be able to use it as a pointer in your header file. Even doing this might prove problematic if you use compiler flags like -pedantic.

    So in short, there is no good way to do this. Your best bet is not to, and access the enum from your implementation (.m) file instead.

    In your implementation file, #import your swift bridging header file, and, without knowing more details about your problem, you could add private properties that use your enum like this:

    @interface MyObjCClassDefinedInTheHFile()
        @property (nonatomic, assign) SomeSwiftEnum type;
    @end
    

    Hope this helps.

    0 讨论(0)
  • 2021-01-31 20:09

    enums are one part of the swift Objective-C communication that does not always work. The thing is that in Objective-C, the enums can just be primitive types(NSInteger for example).

    In swift you can have enums on more types, for example like String. Which is one of the awesome things about swift.

    However, these enums wont be compiled to Objective-C because there is no equivalent for them. So they will simply be ignore and not generated in this header file that xcode creates for all your swift files. This is called Objective-C generated interface header:

    This generated file contains all the classes and enums available in objective-c . You have to mark everything you want to expose in Objective-c with @objc or make them public. You dont need any forward declaration for them to work, if you have this.

    Hope this helps you figure out why your enum is not visible in Objc. Let me know if it worked out.

    0 讨论(0)
  • 2021-01-31 20:12

    As far as I can tell, raf's answer is still correct. The cleanest solution is to simply leave your enum in an Objective-C file until you no longer need to access it from an Objective-C header. I wanted to offer another possible workaround, though.

    In my case I am gradually rewriting a large Objective-C project in Swift, and I don't mind an imperfect workaround if it allows me to rewrite more of my code in Swift. So I've settled on simply passing the enum to Objective-C as it's raw type, Int, or NSInteger to Objective-C. For example:

    - (void)doSomethingWithType:(NSInteger)rawType {
        if (rawType == ExampleTypeWhatever) {
            // Do something
        } // etc...
    }
    

    When I call this method from Swift, all I have to do is pass the .rawType, instead of the actual enum value:

    objcObject.doSomething(withType: ExampleType.whatever.rawValue)
    

    This keeps things fairly simple on both sides, and it'll be easy to update once doSomethingWithType: is eventually rewritten in Swift.

    0 讨论(0)
  • 2021-01-31 20:14

    In Mixed OBJC - Swift projects the best way to have enums work in both types of classes will be to define the enum in an OBJC header and not in a swift class. swift enums can't be used in OBJC header files taken from the answer here

    0 讨论(0)
  • 2021-01-31 20:14

    I just use NSInteger as return type for both header and implementation files. And when you need to use the enum, get the enum by let yourEnum = YourEnum(rawValue: Int(enumNSInteger)). This works for me.

    0 讨论(0)
提交回复
热议问题