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

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

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

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

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

UPDATE:

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

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

Быстрое исправление (но не решение основной причины) заключается в следующем: CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = ДА

Ответ 1

Публичен ли ваш заголовок?

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

public header

Ответ 2

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

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

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

Чтобы открыть библиотеку Objective-C/C для вашего кода быстрой разработки, мы должны определить отдельный быстрый модуль для такой библиотеки. Тогда можно использовать стандартный 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 затем сможет генерировать быстрые привязки для этих C-интерфейсов.

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

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

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

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

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

import SwiftLibXML2

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

Ответ 3

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

Добавьте этот фрагмент в конец вашего подфайла:

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

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

В Swift:

1. Измените проект Xcode и настройки "Настройки сборки", как указано ниже:

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

Включить биткод: Да

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

GoogleMaps (1.10.4)

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

//import GoogleMaps

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

[Название проекта Xcode] -Bridging-Header.h

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

5. Очистите и перестройте проект Xcode.

Ответ 7

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

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

enter image description here

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

Ответ 8

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

Ответ 9

Не

#import "MyOtherFramework.h"

Do

#import <MyOtherFramework/MyOtherFramework.h>

Ответ 10

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

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

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

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

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

Ответ 11

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

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

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

Вот мои 2 добавления к вышеуказанным ответам:

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

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

Ответ 12

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

Ответ 13

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

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

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

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

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

Ответ 14

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

Ответ 15

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

Ответ 16

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

Ответ 17

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

#import <YandexMobileMetrica/YandexMobileMetrica.h>

Ответ 18

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

Ответ 19

Я решил удалить папку Modules из фреймворка.

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

  • Зайдите в папку Test.framework (в приведенном выше примере это будет SOGraphDB.framework) и Delete Modules.

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

Ответ 20

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

Неопределенные символы для архитектуры x86_64

Ответ 21

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