将一系列枚举从Swift桥接到Objective-C

时间:2023-01-15 18:34:09

Since Swift 1.2 it's been possible to automatically convert enums in Swift to Objective-C. However, as far as I can tell, it is not possible to convert an array of enums. Is this true?

从Swift 1.2开始,可以自动将Swift中的枚举转换为Objective-C。但是,据我所知,无法转换枚举数组。这是真的?

So, this is possible:

所以,这是可能的:

@objc public enum SomeEnumType: Int {
    case OneCase
    case AnotherCase
}

But this is not:

但这不是:

public func someFunc(someArrayOfEnums: Array<SomeEnumType>) -> Bool {
    return true
}

Can anyone verify this? And how would you recommend working around this? One approach would be to have two method declarations e.g:

任何人都可以验证吗?你会如何推荐解决这个问题?一种方法是有两个方法声明,例如:

// This will not automatically get bridged.
public func someFunc(someArrayOfEnums: Array<SomeEnumType>) -> Bool {
    return true
}

// This will automatically get bridged.
public func someFunc(someArrayOfEnums: Array<Int>) -> Bool {
    return true
}

But this is polluting the Swift interface. Any way to hide the second function declaration for any Swift consumers?

但这会污染Swift接口。有没有办法隐藏任何Swift消费者的第二个函数声明?

2 个解决方案

#1


9  

It seems, we cannot expose Array<SomeEnumType> parameter to Obj-C even if SomeEnumType is @objc.

看来,即使SomeEnumType是@objc,我们也不能将Array 参数暴露给Obj-C。

As a workaround, how about:

作为一种解决方法,如何:

@objc(someFunc:)
func objc_someFunc(someArrayOfEnums: Array<Int>) -> Bool {
    return someFunc(someArrayOfEnums.map({ SomeEnumType(rawValue: $0)! }))
}

func someFunc(someArrayOfEnums: Array<SomeEnumType>) -> Bool {
    return true
}

#2


-1  

Unfortunately an enum is not transferrable to Swift from Objective-C, it needs to be an NS_ENUM. I had the similar experience to you. The workaround I did was to create an Objective-C category that contains an NS_ENUM and there I transfer the values from the framework enum to my own NS_ENUM.

不幸的是,枚举不能从Objective-C转移到Swift,它需要是一个NS_ENUM。我有类似的经历给你。我做的解决方法是创建一个包含NS_ENUM的Objective-C类,然后我将值从框架枚举转移到我自己的NS_ENUM。

Import the category in your bridging header and you should be able to use the enum as you normally would do.

在桥接标题中导入类别,您应该能够像通常那样使用枚举。

Something like this:

像这样的东西:

typedef NS_ENUM(NSUInteger, ConnectionStatus) {
    ConnectionStatusIdle
}

- (ConnectionStatus)connectionStatus {
    if [self getConnectionStatus] == WF_SENSOR_CONNECTION_STATUS_IDLE {
        return ConnectionStatusIdle
    }
}

Then you should be able to use it like this:

然后你应该能够像这样使用它:

switch myObject.connectionStatus() {
    case .Idle:
        // do something
        break
}

#1


9  

It seems, we cannot expose Array<SomeEnumType> parameter to Obj-C even if SomeEnumType is @objc.

看来,即使SomeEnumType是@objc,我们也不能将Array 参数暴露给Obj-C。

As a workaround, how about:

作为一种解决方法,如何:

@objc(someFunc:)
func objc_someFunc(someArrayOfEnums: Array<Int>) -> Bool {
    return someFunc(someArrayOfEnums.map({ SomeEnumType(rawValue: $0)! }))
}

func someFunc(someArrayOfEnums: Array<SomeEnumType>) -> Bool {
    return true
}

#2


-1  

Unfortunately an enum is not transferrable to Swift from Objective-C, it needs to be an NS_ENUM. I had the similar experience to you. The workaround I did was to create an Objective-C category that contains an NS_ENUM and there I transfer the values from the framework enum to my own NS_ENUM.

不幸的是,枚举不能从Objective-C转移到Swift,它需要是一个NS_ENUM。我有类似的经历给你。我做的解决方法是创建一个包含NS_ENUM的Objective-C类,然后我将值从框架枚举转移到我自己的NS_ENUM。

Import the category in your bridging header and you should be able to use the enum as you normally would do.

在桥接标题中导入类别,您应该能够像通常那样使用枚举。

Something like this:

像这样的东西:

typedef NS_ENUM(NSUInteger, ConnectionStatus) {
    ConnectionStatusIdle
}

- (ConnectionStatus)connectionStatus {
    if [self getConnectionStatus] == WF_SENSOR_CONNECTION_STATUS_IDLE {
        return ConnectionStatusIdle
    }
}

Then you should be able to use it like this:

然后你应该能够像这样使用它:

switch myObject.connectionStatus() {
    case .Idle:
        // do something
        break
}