在swift中使用非NS_ENUM objective-C枚举

时间:2014-07-25 04:29:53

标签: swift

我正在使用wahoo fitness API,它定义了以下Objective-C enum:

typedef enum
{
    /** No active connection. */
    WF_SENSOR_CONNECTION_STATUS_IDLE,
    /** The connection is in process of being established. */
    WF_SENSOR_CONNECTION_STATUS_CONNECTING,
    /** The sensor connection is established and active. */
    WF_SENSOR_CONNECTION_STATUS_CONNECTED,
    /** The connection was interrupted (usually occurs when fisica is disconnected). */
    WF_SENSOR_CONNECTION_STATUS_INTERRUPTED,
    /** The connection is in process of being disconnected. */
    WF_SENSOR_CONNECTION_STATUS_DISCONNECTING,

} WFSensorConnectionStatus_t;

我无法在swift中找到使用它的方法。我首先尝试在其上做一个开关/案例但没有成功。我只是想继续并尝试以下内容:

var connState : WFSensorConnectionStatus_t = WF_SENSOR_CONNECTION_STATUS_IDLE
...
if( connState == WF_SENSOR_CONNECTION_STATUS_IDLE){

但它没有编译:

'WFSensorConnectionStatus_t' is not convertible to 'NSObject'

任何解决方法?我读过使用WFSensorConnectionStatus_t.WF_SENSOR_CONNECTION_STATUS_IDLEWF_SENSOR_CONNECTION_STATUS_IDLE.value但它在xcode beta-4中不起作用。

4 个答案:

答案 0 :(得分:16)

使用.value获取基础整数的解决方法从Beta 4开始不再有效,正如您所说。

不幸的是,enum无法从Objective-C转移到Swift,它必须是NS_ENUM

我在项目中拥有与您相同的设置,我需要来自Objective-C框架的enum并在Swift中使用它。

我所做的解决方法是创建一个包含NS_ENUM的Objective-C类别,然后将值从框架enum传输到我自己的NS_ENUM

在桥接标题中导入类别,您应该可以像往常一样使用enum

这样的事情:

typedef NS_ENUM(NSUInteger, ConnectionStatus) {
    ConnectionStatusIdle
}

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

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

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

答案 1 :(得分:3)

这是最终的完整解决方案:

WFSensorConnection+SensorConnectionEnumCategory.h

#import <Foundation/Foundation.h>

#import <WFConnector/WFConnector.h>

@interface WFSensorConnection (SensorConnectionEnumCategory)

typedef NS_ENUM(NSUInteger, ConnectionStatus) {
    ConnectionStatusIdle,
    ConnectionStatusConnecting,
    ConnectionStatusConnected,
    ConnectionStatusInterrupted,
    ConnectionStatusDisconnecting
};

- (ConnectionStatus) swift_connectionStatus;

@end

WFSensorConnection+SensorConnectionEnumCategory.m

#import "WFSensorConnection+SensorConnectionEnumCategory.h"

@implementation WFSensorConnection (SensorConnectionEnumCategory)

- (ConnectionStatus) swift_connectionStatus{
    if ( [self connectionStatus] == WF_SENSOR_CONNECTION_STATUS_IDLE ){
        return ConnectionStatusIdle;
    } else if ( [self connectionStatus] == WF_SENSOR_CONNECTION_STATUS_CONNECTING ){
        return ConnectionStatusConnecting;
    } else if ( [self connectionStatus] == WF_SENSOR_CONNECTION_STATUS_CONNECTED ){
        return ConnectionStatusConnected;
    } else if ( [self connectionStatus] == WF_SENSOR_CONNECTION_STATUS_DISCONNECTING ){
        return ConnectionStatusDisconnecting;
    } else if ( [self connectionStatus] == WF_SENSOR_CONNECTION_STATUS_INTERRUPTED ){
        return ConnectionStatusInterrupted;
    }
    return 0;
}

@end

Bridging-Header.h

#import "WFSensorConnection+SensorConnectionEnumCategory.h"

用法:

var sensorConnection: WFSensorConnection?
var connState : ConnectionStatus = ConnectionStatus.Idle
connState = sensorConnection!.swift_connectionStatus()
switch connState {
    case ConnectionStatus.Idle:
...
}

答案 2 :(得分:3)

UInt32一样在Swift中导入C风格的枚举。所以你可以这样做:

let state = unsafeBitCast(WF_SENSOR_CONNECTION_STATUS_IDLE, UInt32.self)
if state == unsafeBitCast(WF_SENSOR_CONNECTION_STATUS_IDLE, UInt32.self) {
    //do something
}

更新:在Swift 2.1(Xcode 7.1 beta 2)中,所有C风格的枚举都符合Equatable,您现在可以像以下一样使用它:

let state = WF_SENSOR_CONNECTION_STATUS_IDLE
if state == WF_SENSOR_CONNECTION_STATUS_IDLE {
    //do something
}

利润:)

答案 3 :(得分:1)

请注意,CoreFoundation类型与名为NS_ENUM的{​​{1}}类似。我在我的主要是C的框架上使用它。是的,Swift确实将它转换为Swift枚举。

CF_ENUM还有类似NS_OPTIONS的内容。