Можно ли использовать Swift Enum в Obj-C?

Я пытаюсь преобразовать часть моего класса Obj-C в Swift. И некоторые другие классы Obj-C по-прежнему используют enum в этом преобразованном классе. Я искал в Документах перед выпуском и не мог найти его или, может быть, пропустил его. Есть ли способ использовать Swift enum в Obj-C Class? Или ссылка на документ этой проблемы?

Вот как я объявил свое перечисление в моем старом коде Obj-C и новом коде Swift.

мой старый код Obj-C:

typedef NS_ENUM(NSInteger, SomeEnum)
{
    SomeEnumA,
    SomeEnumB,
    SomeEnumC
};

@interface SomeClass : NSObject

...

@end

мой новый Swift Code:

enum SomeEnum: NSInteger
{
    case A
    case B
    case C
};

class SomeClass: NSObject
{
    ...
}

Обновление: Из ответов. Это не может быть сделано в более ранней версии Swift, чем 1.2. Но в соответствии с этим официальным Swift Blog. В Swift 1.2, выпущенном вместе с XCode 6.3, вы можете использовать Swift Enum в Objective-C, добавив @objc перед enum

Ответ 1

С Swift версии 1.2 (Xcode 6.3) вы можете. Просто префикс объявления enum с помощью @objc

@objc enum Bear: Int {
    case Black, Grizzly, Polar
}

Бесстыдно взято из Swift Blog


В Objective-C это будет выглядеть как

Bear type = BearBlack;
switch (type) {
    case BearBlack:
    case BearGrizzly:
    case BearPolar:
       [self runLikeHell];
}

Ответ 2

Из Использование Swift с Cocoa и Objective-C:

Класс Swift или протокол должны быть отмечены атрибутом @objc для быть доступным и использоваться в Objective-C. [...]

У вас есть доступ к чему-либо в классе или протоколе, который отмеченный атрибутом @objc, если он совместим с Objective-C. Это исключает функции Swift, такие как перечисленные здесь:

Generics Tuples/ Перечисления, определенные в Swift/Структуры, определенные в Функции Swift/Top-level, определенные в переменных Swift/Global, определенных в Swift/Typealiases, определенные в вариациях Swift/Swift/Вложенные типы/ Выполненные функции

Итак, нет, вы не можете использовать переименование Swift в классе Objective-C.

Ответ 3

Чтобы расширить выбранный ответ...

Можно разделить переменные стиля Swift между Swift и Objective-C с помощью NS_ENUM().

Их просто нужно определить в контексте Objective-C, используя NS_ENUM(), и они становятся доступными с использованием нотации Swift.

Из Использование Swift с Cocoa и Objective-C

Быстрое импортирование в виде перечисления Swift перечисляет C-стиль, обозначенный макросом NS_ENUM. Это означает, что префиксы для имен значений перечисления усекаются, когда они импортируются в Swift, независимо от того, определены ли они в системных рамках или в пользовательском коде.

Objective-C

typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
   UITableViewCellStyleDefault,
   UITableViewCellStyleValue1,
   UITableViewCellStyleValue2,
   UITableViewCellStyleSubtitle
};

Свифта

let cellStyle: UITableViewCellStyle = .Default

Ответ 4

Если вы предпочитаете сохранять коды ObjC как-они-есть, вы можете добавить в проект вспомогательный заголовочный файл:

Swift2Objc_Helper.h

в файле заголовка добавьте этот тип перечисления:

typedef NS_ENUM(NSInteger, SomeEnum4ObjC)
{
   SomeEnumA,
   SomeEnumB
};

В вашем файле .m может быть другое место, чтобы внести изменения: включить скрытый заголовочный файл:

#import "[YourProjectName]-Swift.h"

замените [YourProjectName] своим именем проекта. Этот файл заголовка предоставляет все Swift определенные классы @objc, перечисления для ObjC.

Вы можете получить предупреждающее сообщение о неявном преобразовании из типа перечисления... Это нормально.

Кстати, вы можете использовать этот вспомогательный файл заголовка для хранения некоторых кодов ObjC, таких как #define константы.

Ответ 5

Если вы (как и я) действительно хотите использовать перечисления String, вы можете создать специализированный интерфейс для objective-c. Например:

enum Icon: String {
    case HelpIcon
    case StarIcon
    ...
}

// Make use of string enum when available:
public func addIcon(icon: Icon) {
    ...
}

// Fall back on strings when string enum not available (objective-c):
public func addIcon(iconName:String) {
    addIcon(Icon(rawValue: iconName))
}

Конечно, это не даст вам удобство автозаполнения (если вы не определяете дополнительные константы в среде objective-c).

Ответ 6

Swift 4.1, Xcode 9.4.1:

1) Swift перечисление должно иметь префикс @objc и быть типом Int:

// in .swift file:
@objc enum CalendarPermission: Int {
    case authorized
    case denied
    case restricted
    case undetermined
}

2) Имя Objective-C - имя переименования + имя случая, например CalendarPermissionAuthorized:

// in .m file:
// point to something that returns the enum type ('CalendarPermission' here)
CalendarPermission calPermission = ...;

// use the enum values with their adjusted names
switch (calPermission) {
    case CalendarPermissionAuthorized:
    {
        // code here
        break;
    }
    case CalendarPermissionDenied:
    case CalendarPermissionRestricted:
    {
        // code here
        break;
    }
    case CalendarPermissionUndetermined:
    {
        // code here
        break;
    }
}

И, конечно же, не забудьте импортировать заголовок моста Swift как последний элемент в списке импорта файлов Objective-C:

#import "MyAppViewController.h"
#import "MyApp-Swift.h"