13

I am using the wahoo fitness API and it defines the following 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. 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.

2
  • You should ⌘-click on WFSensorConnectionStatus_t to see how it is imported into Swift. This is not NS_ENUM, as NS_ENUM does not appear in the code you posted. Commented Jul 25, 2014 at 4:34
  • I have the same question, need help! Commented Jul 25, 2014 at 7:35

4 Answers 4

17

The workaround to use .value to get the underlying integer doesn't work anymore as of Beta 4, as you said.

Unfortunately an enum is not transferrable to Swift from Objective-C, it needs to be an 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.

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.

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
}
Sign up to request clarification or add additional context in comments.

Comments

4

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:
...
}

Comments

3

C-style enums import in Swift like UInt32. 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:

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

Profit :)

Comments

1

Note that there is a CoreFoundation type that is similar to NS_ENUM called CF_ENUM. I've used it on my framework that is mainly C. And yes, Swift does translate it to a Swift enum.

There is also something similar for NS_OPTIONS called CF_OPTIONS.

1 Comment

NS_OPTIONS is the magical word to translate an Objective-C set of binary options into a swift OptionSet. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.