简体   繁体   English

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

[英]Using non NS_ENUM objective-C enum in swift

I am using the wahoo fitness API and it defines the following objective-C enum: 我正在使用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;

I can't find a way to use it in swift. 我无法找到一种在swift中使用它的方法。 I first tried to do a switch/case on it without success. 我首先尝试在其上做一个开关/案例但没有成功。 I am at a point I just want to carry on and tried the following: 我只是想继续并尝试以下方面:

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

But it does not compile: 但它没有编译:

'WFSensorConnectionStatus_t' is not convertible to 'NSObject'

Any workaround? 任何解决方法? I read to use WFSensorConnectionStatus_t.WF_SENSOR_CONNECTION_STATUS_IDLE or WF_SENSOR_CONNECTION_STATUS_IDLE.value but it does not work in xcode beta-4. 我读取使用WFSensorConnectionStatus_t.WF_SENSOR_CONNECTION_STATUS_IDLEWF_SENSOR_CONNECTION_STATUS_IDLE.value但它在xcode beta-4中不起作用。

The workaround to use .value to get the underlying integer doesn't work anymore as of Beta 4, as you said. 正如您所说,使用.value获取基础整数的解决方法在Beta 4中不再起作用。

Unfortunately an enum is not transferrable to Swift from Objective-C, it needs to be an NS_ENUM . 不幸的是, enum不能从Objective-C转移到Swift,它需要是一个NS_ENUM

I have the same setup as you in a project where I need the enum from an Objective-C framework and use it in Swift. 我在一个项目中有与你相同的设置,我需要一个Objective-C框架的enum ,并在Swift中使用它。

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 . 我做的解决方法是创建一个包含NS_ENUM的Objective-C类,然后我将值从框架enum转移到我自己的NS_ENUM

Import the category in your bridging header and you should be able to use the enum as you normally would do. 在桥接标题中导入类别,您应该能够像通常那样使用enum

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
}

Here is the final complete solution: 这是最终的完整解决方案:

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"

Usage: 用法:

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

C-style enums import in Swift like UInt32 . UInt32一样在Swift中导入C风格的枚举。 So you can do something like: 所以你可以这样做:

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

Upd: In Swift 2.1 (Xcode 7.1 beta 2) all C-style enums conforms Equatable and you can now use it like: 更新:在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
}

Profit :) 利润:)

Note that there is a CoreFoundation type that is similar to NS_ENUM called CF_ENUM . 请注意,CoreFoundation类型与NS_ENUM类似,称为CF_ENUM I've used it on my framework that is mainly C. And yes, Swift does translate it to a Swift enum. 我在我的主要是C的框架上使用它。是的,Swift确实将它转换为Swift枚举。

There is also something similar for NS_OPTIONS called CF_OPTIONS . 也有类似的东西, NS_OPTIONS称为CF_OPTIONS

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM