37

I need to define a protocol which can be called in a class that use some Objective-c type

But doing that doesn't work:

enum NewsCellActionType: Int {
    case Vote = 0
    case Comments
    case Time
}

@objc protocol NewsCellDelegate {
    func newsCellDidSelectButton(cell: NewsCell, actionType: NewsCellActionType)
}

You get he error

Swift enums cannot be represented in Objective-C

If I don't put the @objc tag on my protocol it'll crash the app as soon as it's called in a class which adopt the protocol AND inherit from an Objective-C type class (like a UIViewController).

So my question is, how should I declare and pass my enum with the @objc tag?

Dimillian
  • 3,616
  • 4
  • 33
  • 53

2 Answers2

63

Apple just announced today that Swift 1.2 (included with xcode 6.3) will support exposing enums to objective-c

https://developer.apple.com/swift/blog/

enter image description here

Oren
  • 5,055
  • 3
  • 34
  • 52
  • 2
    For info: This appears to apply only to enums of type Int. Applying @objc to an enum of type String yields the following compilation error: "'@objc' enum raw type 'String' is not an integer type." – Vince O'Sullivan Jun 04 '15 at 10:25
  • 1
    objc (and many other languages) only support enums in ints. swift is unique in this regard – Oren Jul 02 '15 at 05:57
  • 2
    Didn't work in Swift 2.0. Swift ENUM was not visible in ObjC – GoodSp33d Dec 08 '15 at 10:03
  • Make sure your enum is of type Int and marked as @objc like the example above – Oren Dec 08 '15 at 17:03
  • It has to be `Int` type that inherits from, because of the obj-c / c enum type representation is different to Swift. – piotr_ch Jul 07 '20 at 14:29
10

Swift enums are very different from Obj-C (or C) enums and they can't be passed directly to Obj-C.

As a workaround, you can declare your method with an Int parameter.

func newsCellDidSelectButton(cell: NewsCell, actionType: Int)

and pass it as NewsCellActionType.Vote.toRaw(). You won't be able to access the enum names from Obj-C though and it makes the code much more difficult.

A better solution might be to implement the enum in Obj-C (for example, in your briding header) because then it will be automatically accessible in Swift and it will be possible to pass it as a parameter.

EDIT

It is not required to add @objc simply to use it for an Obj-C class. If your code is pure Swift, you can use enums without problems, see the following example as a proof:

enum NewsCellActionType : Int {
    case Vote = 0
    case Comments
    case Time
}

protocol NewsCellDelegate {
    func newsCellDidSelectButton(cell: UITableViewCell?, actionType: NewsCellActionType    )
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, NewsCellDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

        self.window!.backgroundColor = UIColor.whiteColor()
        self.window!.makeKeyAndVisible()

        test()

        return true;
    }

    func newsCellDidSelectButton(cell: UITableViewCell?, actionType: NewsCellActionType) {
        println(actionType.toRaw());
    }

    func test() {
        self.newsCellDidSelectButton(nil, actionType: NewsCellActionType.Vote)
    }
}
Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • Right, my code is pure swift, but it crash, related to my other question here: http://stackoverflow.com/questions/24137090/custom-uitableviewcell-delegate-pattern-in-swift – Dimillian Jun 10 '14 at 12:39
  • You should have left your edit, your question answer mine perfectly, but as you stated, my code is pure Swift. I assumed the crash was because I don't prefixed it with the @objc tag. But sound like I'm wrong. – Dimillian Jun 10 '14 at 12:41
  • @Dimillian77 Sorry, I did an invalid edit and had to write it again. – Sulthan Jun 10 '14 at 12:43
  • Unless of course you require optional values for your protocol... Highly irritating... oh well. – Morkrom Dec 03 '14 at 23:22