pkamb
July 25, 2019, 8:43pm
1
I need to get the string value of a non-String enum.
enum Numbers: UInt {
case one = 1
case two = 2
}
let one = String(describing: Numbers.one) // "one"
let two = String(describing: Numbers.two) // "two"
This seems to work fine and return the case name string for the given case.
But for a certain enum within Apple's frameworks, which is NOT visibly declared as @objc
:
public enum FIMenuKind : UInt {
case contextualMenuForItems
case contextualMenuForContainer
case contextualMenuForSidebar
case toolbarItemMenu
}
it returns the enum name "FIMenuKind"
instead:
import Cocoa
import FinderSync
let menu1 = String(describing: FIMenuKind.contextualMenuForItems) // "FIMenuKind"
let menu2 = String(describing: FIMenuKind.contextualMenuForContainer) // "FIMenuKind"
let menu3 = String(describing: FIMenuKind.contextualMenuForSidebar) // "FIMenuKind"
let menu4 = String(describing: FIMenuKind.toolbarItemMenu) // "FIMenuKind"
Is this a bug in the private implementation of this particular enum?
Is there some other way to get the case name?
Alejandro
(Alejandro Alonso)
July 25, 2019, 9:04pm
2
I assume this is an objc enum which does not store enum case names at runtime.
1 Like
Joe_Groff
(Joe Groff)
July 25, 2019, 9:10pm
3
Yep. ObjC enums don't have runtime metadata to print as their source-level names, so unfortunately, you'd have to extend them to be CustomStringConvertible yourself in order to print them.
2 Likes
pkamb
July 25, 2019, 9:12pm
4
I added the public enum declaration to the question.
Neither the enum nor anything in the FinderSync file have objc
declared.
Is it possible that's declared privately?
mayoff
(Rob Mayoff)
July 26, 2019, 6:15am
5
The generated Swift interface for Objective-C types doesn't include the @objc
modifier. The FIMenuKind
type is nevertheless defined in Objective-C, in FinderSync.h
in the FinderSync
framework.
2 Likes
I encountered a similar issue with a refined C enum
__attribute__((swift_name("Enum")))
typedef enum __attribute__((enum_extensibility(closed))) {
EnumCaseA __attribute__((swift_name("a"))),
EnumCaseB __attribute__((swift_name("b"))),
} ModuleEnum;
Bit unfortunate that these lack case metadata and it has to be supplied in a Swift implementation, since enums of this kind otherwise import very nicely into Swift.