2016-11-08 4 views
18

Я пытаюсь работать над смешанным проектом Swift и ObjectiveC без везения.ModuleName-Swift.h файл не найден в xcode8

Мой проект состоит из 6 целей:

  • App
  • Ядро
  • CoreTest
  • Резюме
  • WatchKit Extension
  • WatchKit App

Я б een может добавить класс Swift, в котором есть одно целевое членство (приложение), и использует код ObjectiveC, проходящий от App-Bridging-Header.h Парадигма «ObjectiveC in Swift» работает как шарм.

Вместо этого я борюсь с парадигмой «Swift into ObjectiveC». В конкретном случае мне нужно использовать новый класс Swift внутри файла ObjectiveC .m, который является членом четырех целей.

То, что я делал до сих пор это:

  1. Добавить новый Swift файл в проект ядра с указанием четыре членства (App, Core, Конспект, WatchKit Ext)
  2. XCode Просит создайте -Bridging-Header.h для трех проектов Core, Summary и WatchKit Ext (App-Bridging-Header.h уже существует, поскольку он использовался ранее), и я согласен (не знаю, почему он создает эти файлы внутри в той же папке группы, где я добавляю свой класс Swift, но никогда не думаю)
  3. Создаю класс Swift, добавив @objc ключ перед тем класс
  4. Я проверю, если Objective-C Сформирован интерфейса Имя заголовка устанавливается для всех модулей, и да это
  5. Я иду проверить, если Определяет модуль установлен в нет во всех модулях и установите да в главном проекте, да и это
  6. записывает импорт для -Swift.h файлов для всех четырех целей
  7. Внутри моего класса Objective-C Я пытаюсь использовать свой новый Swift класс, судя по всему, кажется, работает (даже автозаполнение)
  8. Я пытаюсь построить проект, но он не говорил, что файл -Swift.h не найдено

Я следовал так Mix and Match guide of Apple темы и многие в том числе this one, что, кажется, по-видимому, для решения тех же проблем шахты, но она не работает.

Также видели this и this, но не работали.

Попробовали также удалить производные данные, а также очистить весь проект несколько раз, не повезло.

EDIT 1: Подробнее

Это заявление моего Swift класса импорт RealmSwift

@objc class MyClass: Object {} 

Это фрагмент использования Быстрой класса внутри ObjectiveC

MyClass *app = [[MyClass alloc] init]; 

Если я избегу использовать #import ...- Swift.h, сборка не позволяет утверждать, что я использую Und eclared idenfier «MyClass», и это звучит.

Если я использую файлы #import ...- Swift.h, он говорит, что модуль X не может найти модуль Y и так далее.

EDIT 2: Swift имя модуля

Глядя на SWIFT_OBJC_INTERFACE_HEADER_NAME свойство каждой цели я видел, что она построена с использованием этого синтаксиса $ (SWIFT_MODULE_NAME) -Swift.h делать я необходимо изменить SWIFT_MODULE_NAME до MODULE_NAME?

EDIT 3: Импорт

Это набор для импорта заголовков Swift в .m ObjectiveC файл. Я использую имена модулей, указанные в относительных свойствах настроек сборки. Обратите внимание на то, что у человека есть символ _ _, так как у цели WatchKit Extension есть пробел в целевом имени.

#import "ProjectName_App-Swift.h" 
#import "ProjectName_Core-Swift.h" 
#import "ProjectName_Summary-Swift.h" 
#import "ProjectName_WatchKit_Extension-Swift.h" 

EDIT 4: Крест видимость -Swift.h файлов

Я судимые следующие действия:

  • Добавлен Swift класс только в выходных App
  • XCode созданных Заголовок моста
  • Введено #import "ProjectName_App-Swift.h" в файле ObjectiveC, используемом только приложением
  • Используется класс Swift внутри этого файла
  • Он компилируется! И я могу использовать класс Swift

Когда класс Swift определен для нескольких целей, а файл ObjectiveC используется этими несколькими целями, он не работает. Ошибки сборки выглядят следующим образом: Файл Target X -> "ProjectName_TargetY-Swift.h" не найден. Кажется, что цель не может видеть другие цели -Swift.h.

Что я делаю неправильно? Спасибо за вашу помощь

+0

Можете ли вы отредактировать способ импорта сгенерированного заголовка Swift? – Sealos

+0

@Sealos добавил импорт в исходный вопрос – LucioB

+0

Я считаю, что вам не хватает имени проекта в импорте заголовка. Не могли бы вы это проверить? Например: «Project_name_WatchKit_Extension-Swift.h» Кроме того, вы можете проверить, в каком модуле файл находится в SomeClass.classForKeyedUnarchiver в быстром файле и получить его. – Sealos

ответ

25

Предположение, сделанное мной в редакторе 4, оказалось правильным. Если проект имеет несколько целей, файлы «-Swift.h» не могут быть импортированы в один файл .m ObjectiveC.

Таким образом, есть одно решение, которое должно быть принято, и необходимо изменить настройку сборки SWIFT_OBJC_INTERFACE_HEADER_NAME и сделать ее одинаковой для разных целей. Для этого изменить команду, которая создает это свойство от $ (SWIFT_MODULE_NAME) -Swift.h до $ (PROJECT_NAME) -Swift.h как описано here

Также можно установить продукт Установка имени модуля в настройках сборки одинакова для ваших модулей (я устанавливаю его в $ (PROJECT_NAME)), так что создаваемый файл -Swift.h имеет одинаковое имя для всех модулей. Это устраняет необходимость добавления/проверки макросов препроцессора.

После выполнения этой операции «Чистая сборка» нажав Alt и перейдите в меню «Продукт». Поскольку имя заголовка распределяется между целевыми объектами, теперь его можно импортировать один раз в файле .m ObjectiveC, и все цели могут быть полезны для классов Swift.

Если после сборки все еще отображается ошибка, убедитесь, что заголовок может быть достигнут с XCode, нажав Cmd на его имя. Он должен открыть файл, который содержит код, подобный этому:

SWIFT_CLASS("_TtC27ProjectName_Summary11MyClass") 
@interface MyClass : NSObject 
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; 
@end 

Если необходимо обеспечить, чтобы эти заголовки генерируются открытым терминал и использовать эту команду

find ~/Library/Developer/Xcode/DerivedData -name "*Swift.h" 

Вы должны увидеть один заголовок для каждого target

Другая проблема, которая произошла со мной после этих изменений, заключается в том, что она начала давать ошибки в коде ObjectiveC, который я не касался. Проблема была из-за позиции импорта, как сообщает here:

Ровно, где в верхней части файла .m вы #import заголовок скрытого шунтирования может сделать разницу. Обычным признаком проблемы является то, что вы получаете ошибку компиляции «Неизвестное имя типа», где неизвестный тип - это класс, объявленный в Objective-C. Решение состоит в том, чтобы #import .h-файл, содержащий объявление для неизвестного типа в ваших файлах Objective-C, перед тем, как вы #import заголовок скрытого моста. Сделать это может быть раздражением, особенно если этот объект Objective-C не нуждается в знании об этом классе, но он решает проблему и позволяет компиляцию продолжить.

В самом конце код компилируется и запускается на устройстве и симуляторе!

+0

@Hiren Вы пытались найти файлы заголовков Swift, используя эту команду из терминала? find ~/Library/Developer/Xcode/DerivedData -name "* Swift.h" – LucioB

+0

Если у вас больше целей, не забудьте сделать Bridging-Header для всех из них. Он работает в моем проекте –

+0

Славный спаситель дня! Именно моя проблема и именно решение! Спасибо, сэр. –

2

У меня была аналогичная проблема, и я почти закончил тем, что провел целый день, выясняя эту проблему, следуя советам других разработчиков в StackOverflow и нескольких других источниках.

Я обновлялся с XCode 7.3.1 до XCode 8.2.1 и Swift 2.2 до Swift 3.0.1.
В моем случае, я понял, файл PROJECT_NAME-Swift.h не получил размещен:

~/Library/Developer/Xcode/DerivedData/PRODUCT-NAME-hdkrxixrxbiorwesffpqvefxsrzl/Build/Intermediates/PRODUCT-NAME.build/Debug/PRODUCT-NAME.build/Objects-normal/x86_64/PRODUCT-NAME-Swift.h.

Я предполагаю, что это как-то пытается передать этот файл заголовок из приведенных выше пути и, следовательно, ошибки. Я вручную скопировал его.После этого не делал чистой сборки. Это решило мою проблему, и быстрый заголовочный файл начал создаваться для дальнейшей компиляции и сборки.

0

Для моего случая, она прекрасно работает в Xcode 8, но файлы с

#import "Project-Swift.h" 

уже отсутствует импорт, как описано LucioB

Использование Xcode 9 удаляет эти ошибки

0

Раствор для мне пришлось импортировать генерируемый заголовок быстрого действия через <> синтаксис:

#import <OtherTargetWithSwiftClass/OtherTargetWithSwiftClass-Swift.h> 
0

Это не решение вопроса, но так как многие могли бы в конечном итоге на этой странице ищет проблемы, что файл <ModuleName>-Swift.h не найден (как и я) Я хотел бы добавить еще одну возможную причину:

Когда в быстром файле возникает проблема компилятора, заголовок может не получить сгенерированный xCode, и, следовательно, файл отсутствует.

По крайней мере, в моем случае <ModuleName>-Swift.h not found исчез, как только я исправил ошибку компиляции в файле Swift.