Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use Swift's Enum in Obj-C?

People also ask

Can I use Swift enum in Objective-C?

From what I understand, you can only import Swift stuff in . m files and there is no way to forward declare an enum in Objective C.

How do I create an enum in Objective-C?

Objective-C Language Enums Defining an enumtypedef NS_ENUM(NSUInteger, MyEnum) { MyEnumValueA = 0, MyEnumValueB = 5, MyEnumValueC = 10, }; You can also specify on the first value and all the following will use it with increment: typedef NS_ENUM(NSUInteger, MyEnum) { MyEnumValueA = 0, MyEnumValueB, MyEnumValueC, };

How do I import a Swift file into Objective-C?

Import Swift code into Objective-C within the same framework: Under Build Settings, in Packaging, make sure the Defines Module setting for that framework target is set to Yes. Import the Swift code from that framework target into any Objective-C .

Can associated values and raw values coexist in Swift enumeration?

The Problem with Associated Values We had to do this because Swift doesn't allow us to have both: raw values and associated values within the same enum. A Swift enum can either have raw values or associated values.


As of Swift version 1.2 (Xcode 6.3) you can. Simply prefix the enum declaration with @objc

@objc enum Bear: Int {
    case Black, Grizzly, Polar
}

Shamelessly taken from the Swift Blog

Note: This would not work for String enums or enums with associated values. Your enum will need to be Int-bound


In Objective-C this would look like

Bear type = BearBlack;
switch (type) {
    case BearBlack:
    case BearGrizzly:
    case BearPolar:
       [self runLikeHell];
}

To expand on the selected answer...

It is possible to share Swift style enums between Swift and Objective-C using NS_ENUM().

They just need to be defined in an Objective-C context using NS_ENUM() and they are made available using Swift dot notation.

From the Using Swift with Cocoa and Objective-C

Swift imports as a Swift enumeration any C-style enumeration marked with the NS_ENUM macro. This means that the prefixes to enumeration value names are truncated when they are imported into Swift, whether they’re defined in system frameworks or in custom code.

Objective-C

typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
   UITableViewCellStyleDefault,
   UITableViewCellStyleValue1,
   UITableViewCellStyleValue2,
   UITableViewCellStyleSubtitle
};

Swift

let cellStyle: UITableViewCellStyle = .Default

From the Using Swift with Cocoa and Objective-C guide:

A Swift class or protocol must be marked with the @objc attribute to be accessible and usable in Objective-C. [...]

You’ll have access to anything within a class or protocol that’s marked with the @objc attribute as long as it’s compatible with Objective-C. This excludes Swift-only features such as those listed here:

Generics Tuples / Enumerations defined in Swift / Structures defined in Swift / Top-level functions defined in Swift / Global variables defined in Swift / Typealiases defined in Swift / Swift-style variadics / Nested types / Curried functions

So, no, you can't use a Swift enum in an Objective-C class.


Swift 4.1, Xcode 9.4.1:

1) Swift enum must be prefixed with @objc and be Int type:

// in .swift file:
@objc enum CalendarPermission: Int {
    case authorized
    case denied
    case restricted
    case undetermined
}

2) Objective-C name is enum name + case name, eg CalendarPermissionAuthorized:

// in .m file:
// point to something that returns the enum type (`CalendarPermission` here)
CalendarPermission calPermission = ...;

// use the enum values with their adjusted names
switch (calPermission) {
    case CalendarPermissionAuthorized:
    {
        // code here
        break;
    }
    case CalendarPermissionDenied:
    case CalendarPermissionRestricted:
    {
        // code here
        break;
    }
    case CalendarPermissionUndetermined:
    {
        // code here
        break;
    }
}

And, of course, remember to import your Swift bridging header as the last item in the Objective-C file's import list:

#import "MyAppViewController.h"
#import "MyApp-Swift.h"

If you prefer to keep ObjC codes as-they-are, you could add a helper header file in your project:

Swift2Objc_Helper.h

in the header file add this enum type:

typedef NS_ENUM(NSInteger, SomeEnum4ObjC)
{
   SomeEnumA,
   SomeEnumB
};

There may be another place in your .m file to make a change: to include the hidden header file:

#import "[YourProjectName]-Swift.h"

replace [YourProjectName] with your project name. This header file expose all Swift defined @objc classes, enums to ObjC.

You may get a warning message about implicit conversion from enumeration type... It is OK.

By the way, you could use this header helper file to keep some ObjC codes such as #define constants.