How to Use Objective-C Enum in Swift

How to use Objective-C enum in Swift

I think this is a bug because Swift should define == for C enums or an "to Int" conversion but it doesn't.

The simplest workaround is redefining your C enum as:

typedef NS_ENUM(NSUInteger, JapaneseFoodType) {
JapaneseFoodType_Sushi = 1,
JapaneseFoodType_Tempura = 2,
};

which will allow LLVM to process the enum and convert it to a Swift enum (NS_ENUM also improves your Obj-C code!).

Another option is to define the equality using reinterpret hack:

public func ==(lhs: JapaneseFoodType, rhs: JapaneseFoodType) -> Bool {
var leftValue: UInt32 = reinterpretCast(lhs)
var rightValue: UInt32 = reinterpretCast(rhs)

return (leftValue == rightValue)
}

Objective-C enum in Swift

These get translated to

countDirection.Up
countDirection.Count

Swift removes as many letters as possible that the enum values have in common with the enumeration name. In your case, with an enumeration called countDirection and a value countDirectionUp, the whole "countDirection" is removed. It's not needed because you know which enum you are using, making your code considerable shorter.

Accessing NS_ENUM of objective-C in Swift

From Language Guide - Interoperability - Interacting with C APIs:

"The prefixes to C enumeration case names are removed when they are imported into Swift, whether they’re defined in system frameworks or
in custom code."

This means your first case in the ObserveType enum have no name after being imported to Swift (which I'm somewhat surprised doesn't yield a compile error). If we were to print out the conversion, it would look something like (conceptually)

typedef NS_ENUM(NSInteger, ObserveType) {
Observe = 0
ObserveAll = 1
};

// imported like ...
enum ObserveType: Int {
case _ = 0 // obviously illegal if applied directly in Swift
case All
}

You could try to access the nameless case by using its rawValue (0), but I would recommend updating the name of the first case in your Obj-C enum, if possible.

if let empty = ObserveType(rawValue: 0) {
print(empty) // prints ""?
}

How to import c enum in swift

When Swift imports usual C-enums, cases are imported as global constants.

As if as follows:

let A = Foo(1)
let B = Foo(2)

You can use them like this:

var someFoo: Foo = A

I'm not sure why these constants are not included in the Generated Interface.


If you can touch your .h file and can import some headers for Objective-C classes, you can use the macro NS_ENUM.

typedef NS_ENUM(NSInteger, Bar) {
A = 1,
B = 2
};

The generated header would be like this:

public enum Bar : Int {


case A

case B
}

(Generated Interface does not show rawValues, but they are 1 and 2 respectively as in the original code.)

But I wonder if this can be your option.

How to make a Swift String enum available in Objective-C?

From the Xcode 6.3 release notes (emphasis added):

Swift Language Enhancements

...

Swift enums can now be exported to Objective-C using the @objc
attribute. @objc enums must declare an integer raw type, and cannot be
generic or use associated values. Because Objective-C enums are not
namespaced, enum cases are imported into Objective-C as the
concatenation of the enum name and case name.

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

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];
}

Using Swift Class and Enum from Objective-C


Isn't the enum implicitly Int?

Not really. Objective-C cannot see a Swift enum at all. In Swift, an enum is an object type. Objective-C has no knowledge whatever of any such object type; its only objects are classes. (In Objective-C, enums are just numbers with names.) Therefore, neither a Swift enum type, nor a method that takes or produces a Swift enum, nor a Swift enum property, is exposed to Objective-C

However, in the special case where you say @objc enum BannerStyle: Int, it is translated into an Objective-C enum for you. So, in Objective-C, names such as BannerStyleDanger and BannerStyleInfo will spring to life. But they will just be integers.

Objective-C enum value into Swift enum

The five size aliases have the (raw) values 1, 3, 6, 7, 8 so declare a Swift enum

enum GNImageSize : Int {
case thumbnail = 1
case small = 3
case medium = 6
case large = 7
case xLarge = 8
}

To use the Int value in Swift use for example

GNImageSize.thumbnail.rawValue

Alternatively create a custom enum with static properties to map the types

enum GNImageSize {
static let thumbnail = GnImageSize(0)
static let small = GnImageSize(3)
static let medium = GnImageSize(6)
static let large = GnImageSize(7)
static let xLarge = GnImageSize(8)
}

I don't understand that in 2018 ObjC frameworks still use the Stone-age syntax typedef enum : NSInteger { ... } Foo; rather than Swift compliant syntax typedef NS_ENUM (NSInteger, Foo) { ... }; The latter syntax exists for 6 years (iOS 6, macOS 10.8).



Related Topics



Leave a reply



Submit