Swift to Objective-C header not created in Xcode 6: как исправить?
Причина проблемы: отсутствие автоматической генерации моста
В Xcode 6 и более новых версиях заголовочный файл «ProjectName-Swift.h» создаётся автоматически, но только при соблюдении нескольких условий. Если файл не появляется, скорее всего, проблема связана с настройками цели сборки или с тем, что Swift-классы не экспортируются корректно.
Шаг 1: Проверьте имя продукта (Product Module Name)
Имя файла «ProjectName-Swift.h» формируется на основе параметра Product Module Name в настройках вашей цели. Убедитесь, что оно задано и не содержит пробелов или специальных символов.
// Путь: Build Settings -> Packaging -> Product Module Name
// Пример: MyProject -> файл будет MyProject-Swift.h
Если имя не задано, Xcode использует имя цели сборки, но это может привести к конфликтам. Установите его явно, например: MyApp.
Шаг 2: Настройте заголовок моста (Objective-C Bridging Header)
Для работы Swift с Objective-C в обе стороны необходим bridging header. Убедитесь, что он правильно настроен:
- В настройках цели (Build Settings) найдите параметр Swift Compiler - General -> Objective-C Bridging Header.
- Укажите путь к файлу, например:
$(SRCROOT)/YourProject/Bridging-Header.h. - Сам файл должен существовать в проекте и содержать импорты нужных Objective-C заголовков.
Без этого bridging header'а Xcode может не генерировать обратный заголовок «ProjectName-Swift.h».
Шаг 3: Убедитесь, что Swift-классы экспортируются правильно
Для того чтобы класс стал видимым в Objective-C, он должен:
- Наследоваться от
NSObject(или другого Objective-C класса). - Быть помечен атрибутом
@objc(или наследовать его от родителя). - Методы, которые нужно вызывать из Objective-C, также должны быть помечены
@objc.
Ваш код уже соответствует этим требованиям, но убедитесь, что класс не объявлен как private или fileprivate — это скрывает его от моста.
Шаг 4: Проверьте настройки «Defines Module»
В Build Settings найдите параметр Packaging -> Defines Module. Установите его в Yes. Это заставляет Xcode генерировать модуль для Swift-кода, что необходимо для создания заголовочного файла.
Шаг 5: Принудительная очистка и пересборка
Иногда Xcode кэширует старые настройки. Выполните следующие действия:
- Закройте Xcode.
- Удалите папку
DerivedData(обычно находится в~/Library/Developer/Xcode/DerivedData). - Откройте проект и сделайте Clean Build Folder (Cmd+Shift+K).
- Соберите проект (Cmd+B).
После этого файл «ProjectName-Swift.h» должен появиться в папке DerivedData (физически его нет в проекте, но он доступен через импорт).
Проверочный код
После всех настроек попробуйте такой пример в Objective-C:
// MyObjCFile.m
#import "MyApp-Swift.h" // замените MyApp на ваш Product Module Name
@implementation MyObjCClass
- (void)testSwift {
MySwiftClass *swiftObj = [[MySwiftClass alloc] init];
NSLog(@"%@", [swiftObj sayHello]);
}
@end
Если файл не находится, проверьте имя модуля ещё раз — это самая частая ошибка новичков.
Итог: проблема обычно решается правильной настройкой Product Module Name, включением Defines Module и созданием bridging header. Если ничего не помогает, проверьте, нет ли в проекте синтаксических ошибок в Swift-файлах — Xcode может не генерировать заголовок, если код не компилируется.
<<Альтернативный подход: использование «@objcMembers» и проверка совместимости
Если первый метод не сработал, попробуйте более простой способ — добавить атрибут @objcMembers к вашему Swift-классу. Это автоматически экспортирует все методы и свойства в Objective-C без необходимости помечать каждый из них отдельно.
import Foundation
@objcMembers class MySwiftClass: NSObject {
func sayHello() -> String {
return "Hello from Swift!"
}
var name: String = "Swift"
}
Также убедитесь, что ваш Objective-C файл не имеет ошибок компиляции — иногда Xcode не генерирует заголовок, если в проекте есть синтаксические ошибки в любом из файлов (даже в Swift-файлах, которые не экспортируются). Выполните Cmd+9 (Issue Navigator) и проверьте, нет ли предупреждений или ошибок.
Ещё одна частая причина — использование пробелов в имени проекта или цели. Например, если проект называется «My Project», Xcode может создать файл с именем «My_Project-Swift.h» (заменяя пробелы на подчёркивания). Проверьте реальное имя модуля в папке DerivedData:
- Откройте
~/Library/Developer/Xcode/DerivedData/. - Найдите папку вашего проекта.
- Перейдите в
Build/Intermediates.noindex/YourProject.build/Debug-iphonesimulator/YourProject.build/DerivedSources/— там должен лежать сгенерированный файл.
Если файл есть, но вы не можете его импортировать, значит, вы используете неверное имя. Скопируйте точное имя из этой папки и используйте его в #import.
Важно: Если вы работаете с фреймворками (не с приложением), то заголовок генерируется только при включении Defines Module и указании Product Module Name. Для обычного приложения этого обычно не требуется.