Why is an Enum returning "EnumName" rather than "caseLabel" for `String(describing:)`?

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?

I assume this is an objc enum which does not store enum case names at runtime.

1 Like

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

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?

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
Terms of Service

Privacy Policy

Cookie Policy