Ошибка компилятора Swift: "немодульный заголовок внутри модуля фреймворка"

Теперь я хотел бы перенести мою инфраструктуру ObjC в Swift, и я получил следующую ошибку:

include of non-modular header inside framework module 'SOGraphDB'

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

Похоже, это связано с функцией модуля, но на данный момент не совсем понятно, как это исправить, знаете ли вы решение?

ОБНОВИТЬ:

Это ошибка компилятора Swift.

ОБНОВЛЕНИЕ 2:

Быстрое решение (но не устранение основной причины) состоит в том, чтобы установить для следующего параметра значение yes: CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES

21 ответ

Решение

Ваш заголовок публичный?

Выберите файл заголовка в проводнике проекта. Затем в разделе справа в xcode вы увидите выпадающий список рядом с целью. Измените это от "проекта" до "общественности". Это сработало для меня.

публичный заголовок

Это ожидаемое поведение компилятора и по очень веской причине.

Я думаю, что большинство людей, сталкивающихся с этими проблемами, вызвано после того, как они переключаются с Application Target в Framework Target и начните добавлять заголовки C и Objective C в зонтичный заголовок фреймворка, ожидая, что он будет вести себя так же, как и заголовок Bridging приложения, который ведет себя по-разному. Заголовок зонтика фактически предназначен для смешанной быстрой среды obj-c, и его цель - представить API-интерфейсы внешнему миру, который есть у вашей платформы в target-c или c. Это означает, что заголовки, которые мы помещаем туда, должны быть в открытом доступе.

Он не должен использоваться как место, которое предоставляет заголовки Objective-C/C, которые не являются частью вашей платформы, быстрому коду вашей платформы. Потому что в этом случае эти заголовки также будут представлены как часть нашего модуля инфраструктуры для внешнего мира, что часто не то, что мы хотим сделать, так как это нарушает модульность. (И именно поэтому параметр " Разрешает немодульные включения в модуле фреймворка" по умолчанию имеет значение " НЕТ").

Чтобы представить библиотеку Objective-C/C в вашем быстром коде фреймворка, мы должны определить отдельный модуль swift для такой библиотеки. Тогда стандартный Swift import YourLegacyLibrary может быть использован.

Позвольте мне продемонстрировать это на некотором типичном сценарии: встраивание libxml2 в наши рамки.

1. Сначала нужно создать module.modulemap файл, который будет выглядеть следующим образом:

Для платформы OSX:

module SwiftLibXML2 [system] {
  header "/usr/include/libxml2/libxml/xpath.h"
  export *
}

Для платформы iOS:

module SwiftLibXML2 [system] {
  header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/libxml2/libxml/xpath.h"
  export *
}

Все, что он делает, - это оборачивает заголовок и любые другие заголовки, на которые он ссылается, внутри модуля swift, так что swift сможет генерировать привязки swift для этих интерфейсов Си.

2. Затем в каталоге проекта xcode создайте папку SwiftLibXML2 и поместите этот module.modulemap там

3. В настройках сборки добавьте $(SDKROOT)/usr/include/libxml2 к путям поиска заголовка

4. В настройках сборки добавьте $(SRCROOT)/SwiftLibXML2 импортировать пути

5. На вкладке " Общие " проекта добавьте libxml2.tbd к связанным структурам и библиотекам.

Теперь вы импортируете этот модуль, где это необходимо, с помощью:

import SwiftLibXML2

(если вы хотите посмотреть более полный пример module.map, я бы предложил ссылку на модуль module.modulemap Дарвина по адресу /usr/include/module.modulemap, вам нужно было бы установить инструменты командной строки Xcode, чтобы перейти туда, ссылка отсутствует /usr/include в OS X El Capitan)

Вот как автоматически применить быстрое исправление, чтобы вам не пришлось менять Pods.xcodeproj вручную после каждого pod install,

Добавьте этот фрагмент в конец вашего Podfile:

post_install do |installer|
  installer.pods_project.build_configuration_list.build_configurations.each do |configuration|
    configuration.build_settings['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
  end
end

Решением для меня было перейти на цель-> настройки сборки-> Разрешить немодульные включения в Framework Modules и переключиться на YES!

В Свифте:

1. Измените ваш проект Xcode и настройки сборки целей, как указано ниже:

Разрешить немодульные включения в каркасные модули: нет

Включить битовый код: да

2. Используйте текущую последнюю версию, доступную для GoogleMaps iOS SDK (используйте CocoaPods для ее получения):

GoogleMaps (1.10.4)

3. Прокомментируйте проблемный импорт:

//import GoogleMaps

4. Создайте или измените файл заголовка моста, добавив проблемный импорт:

[Ваше имя проекта XCode] -Bridging-Header.h

// Use this file to import your target's public headers 
// that you would like to expose to Swift.
#import <GoogleMaps/GoogleMaps.h>

5. Очистите и пересоберите свой проект XCode.

Я думаю, я справился с этим. У меня есть некоторый код модели, который использует sqlite3 в рамках. В моем случае виновником был .

Проблема заключалась в том, что в моем заголовке Module/Module.h я импортировал публичный заголовок, который импортировал . Решением было скрыть все типы sqlite3_xxx и убедиться, что они не видны ни в одном публичном.h. Все прямые ссылки на sqlite3 были сделаны частными или видимыми для проекта. Например, у меня был публичный синглтон, на котором висели некоторые указатели sqlite3_stmt. Я переместил их в отдельный класс, который теперь является только предварительным объявлением в этом общедоступном заголовке. Теперь я могу строить.

Кстати, настройка CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES не работает. Я попытался установить его как в рамках, так и в зависимом проекте. Этот обходной путь был необходим, хотя я не уверен, почему.

не

#import "MyOtherFramework.h"

Делать

#import <MyOtherFramework/MyOtherFramework.h>

Этот ответ устарел.

При импорте фреймворков вы должны импортировать все файлы заголовков, которые имеют общие зависимости с корневым заголовком. Самый простой способ убедиться, что это всегда работает, - импортировать все заголовки в папке "Заголовки" фреймворка в общий путь к заголовкам.

Компилятор Swift использует эту информацию для генерации карты не искаженных символов вместе с информацией об их связанном типе.

Переключение параметров сборки> Разрешить немодульные включения в Framework Modules в YES! решил ту же проблему для меня.

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

Я знаю, что это старый вопрос, но у меня была такая же проблема, и ничто из вышеперечисленного не помогло мне. Поэтому я надеюсь, что мой ответ будет полезен для кого-то. В моем случае проблема была в настройке ALWAYS_SEARCH_USER_PATHS. Когда он был установлен на NO, проект строился и работал нормально. Но поскольку один из модулей требовал, чтобы он был установлен в ДА, я получал ошибку

Включение немодульного заголовка внутри модуля фреймворка

После пары чашек кофе и целого дня исследований я обнаружил, что в соответствии с известными проблемами Xcode 7.1 Beta 2 заметки о выпуске:

• Если вы получили сообщение об ошибке "Включение немодульного заголовка в модуль фреймворка" для ранее скомпилированной платформы, убедитесь, что для параметра сборки "Всегда искать пути пользователя" установлено значение "Нет". По умолчанию "Да" только по устаревшим причинам. (22784786)

Я использовал XCode 7.3, но, похоже, эта ошибка еще не исправлена.

Я хотел бы добавить свой опыт с этой проблемой.

Просто подведу итог:

  • Ответ @ambientlight отличный, и он решает большинство проблем.
  • разрешение немодульных заголовков - другое решение (см. некоторые ответы выше).
  • помечая заголовки фреймворка как общедоступные (только те, которые вы хотите предоставить) и импортируя их в зонтичный заголовок.

Вот мои 2 дополнения к вышеупомянутому ответу (ответам):

  • тщательно проверяйте импорт в вашем проекте для заголовков, которые импортируют ваши фреймворки непосредственно в них (вместо использования предварительного объявления, если это возможно) - не рекомендуется включать файл заголовка в другой файл заголовка; иногда это вызывает проблемы, потому что, если не сделано должным образом, это может привести к множественному включению одного заголовка и создать проблемы компоновщика.
  • ОБНОВЛЕНИЕ: убедитесь, что архитектуры библиотеки и цели, с которой вы хотите связать ее, совпадают.
  • и, наконец, после всего вышеперечисленного, я все еще продолжал сталкиваться с этой ошибкой. Поэтому я покопался еще немного и обнаружил (на форумах разработчиков Apple, но потерял ссылку:(), что если вы включите заголовки в заголовок зонтика, не так <framework/headerName.h>, но только так "headerName.h"проблема уходит.

Я попробовал этот последний, и до сих пор у меня больше не возникало этой проблемы, однако я подозреваю, что это решение действительно только в том случае, если вы применили некоторые из лучших ответов (примечание: они, например, несовместимы друг с другом, модульный подход и разрешение немодульного заголовка включает).

Я перепробовал все возможные решения, которые я нашел в этой теме, установив цель-> настройки сборки-> Разрешить немодульные включения в модули Framework, переключитесь на YES! и т.д.

Но ничего не сработало.

Я начал получать эту ошибку, когда устанавливал модули, комментируя use_frameworks! , потому что я хотел иметь статическую библиотеку для модулей.

Причина Компилятор Swift выдает (в Xcode 13) эту ошибку, потому что я импортировал заголовок частной структуры #import «TFLTensorFlowLite.h» в общедоступный файл .h, поэтому я импортировал его в файл .m, как показано на снимках экрана ниже, и он перестал выдавать эту ошибку с помощью компилятора Swift (обратите внимание, что в моем фреймворке был как Objective c, так и быстрый код)

Я получил эту проблему после обновления проекта с swift2 на swift3. Я использовал XCode 8.3.2 для обновления кода и не смог избавиться от ошибки "немодульный заголовок внутри модуля фреймворка". Когда я открыл тот же проект в другой версии XCode (версия 9.0.1), ошибка не появилась.

В моем случае (Xcode 9 beta 6 - Swift 4 - с использованием Cocoapods) это было решено, когда я удалил Podfile.lock и каталог Pods и запустил pod install снова

У меня была конкретная проблема с Facebook 4.02 SDK и FBSDKCoreKit.

Я сделал все шаги, но все еще ошибка о немодульном заголовке. я перетащил только определенный заголовок из каркаса, чтобы построить фазы-> заголовок раздела.

Затем автоматически создается копия заголовка в навигаторе проекта вверху.

Я удалил его из фаз сборки -> заголовок и удалил новый файл и работал нормально.

Как это сброшено или что-то.

У меня была именно эта проблема при включении моей собственной структуры в проект. Исправлена ​​ошибка, при которой все импорта sqlite3.h помещались в файлы.m, а не в публичные.h. Я предполагаю, что другие библиотеки могут отмечать аналогичные проблемы с Xcode.

Чаще всего эта ошибка вызвана выбранным ответом, но у меня эта ошибка появлялась однажды случайно при перетаскивании файлов фреймворка в папку моего нового проекта. Я щелкнул, чтобы удалить рамки, но случайно нажал только "Удалить ссылку" на рамки, а не фактически полностью удалить файлы. На этом этапе, если я открыл папку своего проекта в Finder, я увидел там файлы типа "CoreLocation" и "AudioToolbox". Удаление этих файлов из папки проекта и очистка проекта устранили проблему.

Я решил это убрав Modules папка из рамок.

  • Перейдите к расположению вашего фреймворка, которое присутствует в проекте приложения с помощью поиска

  • Проходи внутрь Test.framework папка (в приведенном выше случае это будет SOGraphDB.framework) & Удалять Modules папка.

  • Очистите и перестройте приложение, оно решит проблему.

После разрешения импорта немодульных включений вы можете попробовать импортировать этот модуль, используя заголовок Objective-C Bridging:

#import <YandexMobileMetrica/YandexMobileMetrica.h>

У меня была эта проблема при импорте фреймворка Parse. Единственный способ исправить это - отменить все мои изменения, так как мой последний коммит (простое удаление фреймворка и очистка проекта не сработал) и снова добавить Parse (после новой загрузки SDK) с другими необходимыми фреймворками.

Другие вопросы по тегам