Не удаётся использовать классы Swift внутри Objective-C в статической библиотеке
Почему возникает проблема
Основная причина — статическая библиотека на Swift не генерирует автоматически заголовочный файл совместимости для Objective-C (ProductModuleName-Swift.h), если не настроена правильно. Swift-классы должны быть явно помечены @objc и наследоваться от NSObject (что вы сделали верно), но для статической библиотеки требуется дополнительная конфигурация.
Пошаговое решение
Вот что нужно сделать, чтобы Swift-классы стали доступны из Objective-C в статической библиотеке:
1. Настройка сборки библиотеки
В проекте вашей статической библиотеки перейдите в Build Settings и установите:
Defines Module— YesProduct Module Name— задайте имя модуля (например,MyLibrary)Install Objective-C Compatibility Header— YesObjective-C Generated Interface Header Name— оставьте по умолчанию ($(PRODUCT_MODULE_NAME)-Swift.h)
2. Маркировка классов
Убедитесь, что все публичные классы и методы, которые вы хотите использовать из Objective-C, помечены @objc и наследуются от NSObject. Ваш пример уже корректен, но для надёжности добавьте @objcMembers к классу:
import Foundation
@objcMembers public class MySwiftClass: NSObject {
public func sayHello() -> String {
return "Hello from Swift!"
}
public var name: String = ""
}
3. Импорт в Objective-C
В Objective-C файле импортируйте сгенерированный заголовок:
#import "MyLibrary-Swift.h"
@implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
MySwiftClass *swiftObject = [[MySwiftClass alloc] init];
swiftObject.name = @"Test";
NSLog(@"%@", [swiftObject sayHello]);
}
@end
4. Проверка флагов линковки
В главном проекте (не в библиотеке) в Build Settings добавьте в Other Linker Flags:
-ObjC— загружает все Objective-C классы из статических библиотек-all_load(если -ObjC не помогает) — загружает все объектные файлы
5. Дополнительная проверка
Если всё ещё не работает, проверьте:
- Что ваша библиотека собрана как Static Library (не Dynamic Framework)
- Что в Build Phases -> Headers ваши Swift-файлы отмечены как Public
- Очистите проект (
Cmd+Shift+K) и пересоберите
Пример полной настройки
Вот минимальный рабочий пример. Swift-файл библиотеки:
// MyClass.swift
import Foundation
@objcMembers public class MyClass: NSObject {
public func greet() -> String {
return "Привет из Swift!"
}
}
Objective-C код в основном проекте:
#import "MyLibrary-Swift.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
MyClass *obj = [[MyClass alloc] init];
NSLog(@"%@", [obj greet]);
return YES;
}
@end
После правильной настройки статическая библиотека сгенерирует файл MyLibrary-Swift.h, и все @objc-классы будут доступны в Objective-C.
Альтернативный подход: использование модулей (Modules)
Если статическая библиотека продолжает создавать проблемы, рассмотрите возможность преобразования её в динамический фреймворк (Dynamic Framework). Это упрощает интеграцию Swift и Objective-C:
- В настройках библиотеки измените Mach-O Type на
Dynamic Library - В главном проекте добавьте фреймворк в Embedded Binaries
- Импортируйте модуль:
@import MyLibrary;(вместо #import)
Преимущества:
- Автоматическая генерация модульного заголовка
- Не нужно вручную настраивать флаги линковки
- Лучшая поддержка Swift-фич (например, extension-ов)
Недостаток: динамические фреймворки увеличивают размер приложения и время запуска, поэтому для небольших проектов статическая библиотека предпочтительнее. Но для быстрого решения проблемы — это надёжный вариант.
Также проверьте, не конфликтуют ли ваши Swift-классы с именами Objective-C классов. Иногда Xcode не генерирует заголовок, если есть дублирование имён.