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

191

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

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

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

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

UPDATE:

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

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

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

  • 3
    Кажется, есть новая настройка сборки для "CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES"
  • 1
    Кто-нибудь видел это на включениях, которые являются общедоступными и модульными? Я вижу это с помощью проекта vanilla (cocoapods): github.com/CocoaPods/CocoaPods/issues/3092 и dropbox.com/s/trhe5vwhzoa9bf5/…
Показать ещё 4 комментария
Теги:
frameworks

20 ответов

308
Лучший ответ

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

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

Изображение 1776

  • 0
    Я принимаю этот ответ, даже если он такой же, как я сказал.
  • 0
    Вы также можете перейти к этапу сборки заголовков вашей инфраструктуры и быстро увидеть, какие заголовки являются общедоступными, проектными и частными.
Показать ещё 7 комментариев
114

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

Я думаю, что большинство людей, сталкивающихся с этими проблемами, вызывается после того, как они переключаются с 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)

  • 1
    Имя файла module.map устарело, его следует переименовать в module.modulemap clang.llvm.org/docs/Modules.html#attributes
  • 0
    Как import SwiftLibXML2 в Objective-C? Спасибо!
Показать ещё 6 комментариев
51

Здесь, как автоматически применить быстрое исправление, поэтому вам не нужно менять 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
29

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

  • 0
    Также работал с Cocoapods здесь. Не нужно делать магию из другого ответа после установки модуля
  • 3
    Я сделал этот шаг ... он работал некоторое время ... и теперь он не работает ... Я также включил шаг pod-install. Но теперь это снова терпит неудачу. Что-нибудь еще, что я должен проверить? Я не вижу GoogleMobileAds.Framework в качестве опции для изменения заголовков на Public.
Показать ещё 3 комментария
15

В 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.

  • 1
    Это очень помогает! Также отлично работает с фреймворком GoogleMobilAds (с Cocoapods)
  • 0
    Это сработало и для Google Analytics.
Показать ещё 1 комментарий
15

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

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

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

  • 0
    Это полностью помогло! В моем случае это была достижимость.
  • 4
    Я почти уверен, что это решение моей проблемы, когда я пытаюсь включить SSZipArchive в свой модуль фреймворка. Открытый заголовок импортирует <zlib.h> и выдает ту же ошибку. Можете ли вы опубликовать свой исходный код где-нибудь, потому что я изо всех сил пытаюсь заставить его работать, так как я понимаю только часть вашего ответа ... спасибо!
5

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

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

Изображение 1777

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

  • 0
    Похоже, это лишает цели наличия файлов Framework, но у меня это сработало. Chartboost и RevMob недавно начали использовать файлы Framework вместо просто библиотек. Копирование всего из их заголовков в заголовки моего приложения решает проблему.
  • 0
    Это единственное решение? У меня есть 6 фреймворков, и у каждого есть около 20 заголовков. Это создает беспорядок. Любой альтернативный?
Показать ещё 1 комментарий
3

Не

#import "MyOtherFramework.h"

Do

#import <MyOtherFramework/MyOtherFramework.h>
3

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

  • 0
    Как именно я могу это сделать? У меня проблемы с заголовочными файлами TwitterKit
2

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

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

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

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

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

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

2

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

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

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

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

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

  • 0
    Это то, что помогло мне! После перехода на NO мне пришлось изменить некоторые операции импорта, но теперь я смог импортировать необходимую структуру!
1

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

1

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

1

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

1

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

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

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

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

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

1

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

0

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

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

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

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

0

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

#import <YandexMobileMetrica/YandexMobileMetrica.h>
0

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

0

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню