Импорт протокола Swift в класс Objective-C

Я пытаюсь импортировать Swift-протокол с именем AnalyticProtocol в класс Objective-C с именем AnalyticFactory.

protocol AnalyticProtocol
{

}

Я начинаю с существующего проекта Objective-C (я не создал новый проект Swift с xCode, и я не нашел, как настроить мой проект Objective-C как проект Swift в xCode 6).

В моем файле Swift я включил файл .h с именем MyProjectName-Swift.h, но компилятор вернул мне ошибку, сообщив мне, что он не существует. Таким образом, я создал файл .h с именем MyProjectName-Swift.h, который на самом деле пуст (я не знаю, что я должен помещать внутри).

В документации Apple они сказали, что я должен включить мой файл .h с именем MyProjectName-Swift.h в мой файл .m. Но мне нужно включить его не в мой .m файл, а в мой .h. Это может быть проблематично?

Когда я пытаюсь скомпилировать, у меня есть эта ошибка: : 0: ошибка: xxxAnalyticFactory.h: 39: не удается найти объявление протокола для "AnalyticProtocol"

И инкриминируемый код:

@interface AnalyticFactory : NSObject
{
    Class<AnalyticProtocol> _analyticProtocolClass; // The type of the analytic class currently used.
}

Я думаю, что не понимаю, как я могу импортировать протокол Swift в класс Objective-C.

Кто-нибудь видит ошибку в том, что я делаю?

Ответ 1

Вам нужно добавить атрибут @objc к вашему протоколу Swift следующим образом:

@objc protocol AnalyticProtocol {

}

Ответ 2

Невозможно импортировать заголовок Swift сгенерированный Xcode в файлы заголовков objC.

Итак, поскольку вы хотите использовать код Swift в заголовочном файле objC, вам нужно будет "переслать объявление" классы и протоколы, которые вы хотите использовать в заголовочном файле objC, например:

@protocol AnalyticProtocol;

Теперь вы можете использовать протокол в объявлении класса objC:

@interface AnalyticFactory : NSObject
{
    Class<AnalyticProtocol> _analyticProtocolClass; // The type of the analytic class currently used.
}

В вашем файле реализации (файл objC.m) вы можете импортировать созданный Xcode заголовок Swift ( "ProductModuleName-Swift.h" ), и правильная реализация AnalyticProtocol теперь будет известна компилятору.

Это также описано в разделе "Использование Swift из Objective-C" в Документах для Apple

Обратите внимание, что XCode выдаст предупреждение в заголовочном файле objC, когда вы используете объявленный вперед протокол ( "Не удается найти определение протокола для" AnalyticProtocol "), но это можно игнорировать - реализация будет найдена во время компиляции.

Ответ 3

Для тех, кому просто нужно принять протокол - вы можете сделать это в два этапа, не генерируя никаких предупреждений или ошибок:

  1. В файле .swift добавьте @objc перед именем протокола:

    @objc protocol AnalyticProtocol {
    
    }
    
  2. В своем файле .m импортируйте сгенерированный заголовок Swift и примите протокол в частной категории. (Заголовочный файл назван автоматически):

    #import "ProductModuleName-Swift.h"
    
    @interface AnalyticFactory () <AnalyticProtocol>
    
    @end
    

Это яблочный рекомендуемый подход. Вы можете узнать больше о смешивании и сопоставлении Objective-C и Swift здесь: https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html

Ответ 4

Если вы создаете фреймворк, требуется импорт

#import "ProductModuleName-Swift.h"

изменения в:

#import <ProductModuleName/ProductModuleName-Swift.h>

В этом случае вы также должны сделать общедоступный протокол:

@objc public protocol AnalyticProtocol {
  func something();
}