GOOGLE ADS

среда, 27 апреля 2022 г.

Файл ModuleName-Swift.h не найден в xcode8

Я безуспешно пытаюсь работать над смешанным проектом Swift и ObjectiveC.

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


  • Приложение

  • Основной

  • CoreTest

  • Резюме

  • Расширение WatchKit

  • Приложение WatchKit


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

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

Что я делал до сих пор, так это:

  • Добавьте новый файл Swift в проект Core, указав четыре членства (App, Core, Summary, WatchKit Ext).

  • XCode просит создать -Bridging-Header.h для трех проектов Core, Summary и WatchKit Ext (App-Bridging-Header.h уже существует, так как он использовался ранее), и я соглашаюсь (не знаю, почему он создает эти файлы внутри та же групповая папка, в которую я добавляю свой класс Swift, но неважно)

  • Я создаю класс Swift, добавляя ключ @objc перед классом

  • Я иду проверить, установлено ли имя заголовка интерфейса Objective-C для всех модулей, и да, это

  • Я проверяю, установлено ли для параметра « Определение модуля » значение «Нет » во всех модулях и установлено значение « Да » в основном проекте, и да, это так.

  • Я записываю импорт для файлов -Swift.h для всех четырех целей

  • Внутри моего класса Objective-C я пытаюсь использовать свой новый класс Swift, кажется, он работает (даже автозаполнение)

  • Я пытаюсь собрать проект, но мне не удается сказать, что файл -Swift.h не найден.

  • Я следил за руководством Apple по смешиванию и сопоставлению и многими потоками SO, включая этот, который, по-видимому, решает ту же проблему, но не работает.

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

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

    РЕДАКТИРОВАТЬ 1: Подробнее

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

    @objc class MyClass: Object {}

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

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

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

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

    РЕДАКТИРОВАТЬ 2: имя модуля Swift

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

    РЕДАКТИРОВАТЬ 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"

    РЕДАКТИРОВАТЬ 4: Перекрестная видимость файлов -Swift.h

    Я пробовал следующее:


    • Добавлен класс Swift только в целевом приложении

    • XCode создал заголовок моста

    • Вставлен #import «ProjectName_App-Swift.h» в файл ObjectiveC, используемый только приложением.

    • Использовал класс Swift внутри этого файла

    • Он компилируется! И я могу использовать класс Swift


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

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


    Решение проблемы

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

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

    Также можно установить для параметра «Имя модуля продукта» в настройках сборки одинаковое значение для всех ваших модулей (я установил для него значение $(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"

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

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

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

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

    Комментариев нет:

    Отправить комментарий

    Laravel Datatable addColumn returns ID of one record only

    Я пытаюсь использовать Yajra Datatable для интеграции DataTable на свой веб-сайт. Я смог отобразить таблицу, но столкнулся с проблемой. В по...