在 swift 中获取 Objective-C 枚举值

Get Objective-C enum value in swift

提问人:SimonEritsch 提问时间:10/29/2023 更新时间:10/30/2023 访问量:70

问:

我是 swift 的新手,我正在尝试解决以下问题。

我有一个框架,我在我的应用程序中使用它。 该框架在 Objective-C 中定义了多个枚举,如下所示:

typedef NS_ENUM(NSUInteger, AdvertType) {
    AdvertTypeLoading,
    AdvertTypeFinished
    ...
};

我有一个带有类似“finished”的字符串的变量,需要自动获取正确的 ENUM 引用。 为此,我尝试了以下代码,但是我一直收到一个错误,没有成员。eventStateAdvertTypeallCases


    for type in AdvertType.allCases {
        if type.state.caseInsensitiveCompare(eventState) == .orderedSame {
            return type;
        }
    }

为什么我的枚举没有,并且有没有其他方法,如何将我的字符串转换为实际的枚举值,我可以在 AdvertType 类型化方法中使用?allCases

有没有更简单的方法?

let eventState = 'loading';

let enumState = AdvertType[eventState];

// should return AdvertType.loading
Swift Objective-C 枚举

评论

0赞 Sweeper 10/29/2023
什么?我假设这是您声明但未在问题中显示的属性?type.stateAdvertType

答:

2赞 son 10/29/2023 #1

CaseIterable是 Swift 的一个协议,它允许你使用属性将枚举中的所有类型作为一个集合来访问,所以没有办法让 Objective-c 枚举符合它。你必须解决这个问题。allCases

方法 1,定义一个 swift 枚举,该枚举将 1-1 映射到 .然后声明一个属性以返回与 Objective-C 中相同的类型,或者从 Swift 编写一个扩展来手动实现属性。感谢@Alex向我指出:AdvertTypeallCases

enum Advert: String, CaseIterable {
    case loading
    case finished

    var enumAdapter: AdvertType {
        switch self {
        case .loading:
            return AdvertType.loading
        case .finished:
            return AdvertType.finished
        }
    }
}

if let loadingState = Advert(rawValue: "loading") {
    //TODO:
}

extension AdvertType {
    public static var allCases: [AdvertType] = [
        .loading,
        ...
    ]
}

方法 2,每次想要获取 Objective-C AdvertType 时,请运行一个 for 循环来获取带有条件的值,就像你在上面所做的那样 type.state...但是,将 rawValue 从 String 更改为 UInt(“loading” -> 0),因为枚举定义了 NSUInteger。

针对方法 2 进行了编辑:我的错误是我没有查看条件,它也在里面.因此,使用 String 输入参数和 UInt 作为初始化枚举参数,无法像上面的示例那样转换如此简单的方法。如果我是你,我会创建一个辅助函数来在它们之间进行转换(我更喜欢方法 1)。但是,请注意意外情况下的 TYPO 和返回类型:type.stateAdvertType

static func getAdvertType(from state: String) -> AdvertType? {
    switch state {
    case "loading":
        return .loading
    case "finished":
        return .finished
    default:
        return nil
    }
}

评论

0赞 SimonEritsch 10/30/2023
感谢您的评论。您介意提供更多细节(例如 2 )吗?不幸的是,第 1 个不起作用,因为库中的枚举可能会更改,我需要我们的代码仍然动态地处理更改,而不必每次都在我的枚举副本中更改它。
0赞 son 10/30/2023
@SimonEritsch我编辑了答案,这里有一个错误。不幸的是,没有这样的方法可以直接转换它们。
1赞 Alexander 10/30/2023
您可以在扩展中手动向 CaseIterable 添加扩展:extension AdvertType: CaseIterable { static var allCases: [AdvertType] = [...] }