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 rawValue
s, 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
How to Open File Dialog with Swiftui on Platform "Uikit for MAC"
Detailed Instruction on Use of Nsopenpanel
How to Use Image Literal in Xcode 13
Key-Value Coding (Kvc) with Array/Dictionary in Swift
Skip Item When Performing Map in Swift
Xcode 8.2.1 Not Showing Documentation Description on Autocomplete
Ycombinator Not Working in Swift
How to Integrate Latest Sdwebimage API in My Swift Based Project
Error: Bool Is Not Convertible to Void:
App Crashes When Trying to Append Data to a Child Value
How to Utilize Nslock to Prevent a Function from Firing Twice
How to Use Unsafemutablerawpointer to Fill an Array
Po Swift String "Unresolved Identifier"
Find Item of Specific Type in Array
How to Properly Implement the Equatable Protocol in a Class Hierarchy
Swift Lazy Subscript Ignores Filter