Использование не NS_ENUM objective-C enum в swift
Я использую API-интерфейс wahoo fitness, и он определяет следующее objective-C перечисление:
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_IDLE
или WF_SENSOR_CONNECTION_STATUS_IDLE.value
, но он не работает в xcode beta-4.
Ответы
Ответ 1
Обходной путь для использования .value для получения базового целого не работает больше с Beta 4, как вы сказали.
К сожалению, enum
не переносится в Swift из Objective-C, он должен быть NS_ENUM
.
У меня такая же настройка, как и в проекте, где мне нужна enum
из рамки Objective-C и использовать ее в Swift.
Обходной путь, который я сделал, заключался в создании категории Objective-C, содержащей NS_ENUM
, и я переношу значения из фреймворка 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
}
Ответ 2
Импорт контейнеров в стиле C в Swift как UInt32
. Поэтому вы можете сделать что-то вроде:
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
Вот окончательное полное решение:
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:
...
}
Ответ 4
Обратите внимание, что существует тип CoreFoundation, который похож на NS_ENUM
, называемый CF_ENUM
. Я использовал его в своих фреймворках, в основном C. И да, Swift действительно переводит его в перечисление Swift.
Существует также нечто подобное для NS_OPTIONS
, называемое CF_OPTIONS
.