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

150

Я использую Xcode 6,

1) Сначала я создаю динамическую библиотеку (CoreLibrary). Эта библиотека содержит файл RequestPoster.h.

2) Затем я создаю Cocoa Touch Framework и добавляю эту динамическую библиотеку (CoreLibrary).

3) Затем этот фреймворк добавляется в мой проект и выдает ошибку в файле RequestPoster.h (CoreLibrary).

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

ifaddrs.h, arpa / inet.h, sys / types.h>

Этих файлов нет в проекте.

Dev
источник

Ответы:

190

Попробуйте перейти в «Параметры сборки» в «Целевой объект» и установите для «Разрешить немодульные включения в модули платформы» значение ДА.

Реальный ответ заключается в том, что местоположение импорта должно быть изменено владельцем библиотеки. Эти файлы ifaddrs.h, arpa / inet.h, sys / types.h импортируются в файл .h во фреймворке, что не нравится Xcode. Сопровождающий библиотеки должен переместить их в файл .m. См., Например, эту проблему на GitHub, где AFNetworking исправила ту же проблему: https://github.com/AFNetworking/AFNetworking/issues/2205

крупный рогатый скот
источник
4
Если заголовок с ошибкой использует тип из импортированных заголовков, что рекомендуется? Например, если header module.h в модуле объявляет функцию, принимающую параметр типа ifaddrs, они привязаны к импорту ifaddrs.h.
Ayush Goel
Но что, если они включены в систему /usr/include/libproc.h?
Ben Leggiero
4
Не могли бы вы объяснить, каково влияние изменений: Разрешить
немодульные
Я думаю, что, возможно, лучшим ответом было бы создание модульного заголовка, а не подавление этой ошибки. Я легко могу представить, как Apple убирает возможность разрешать немодульные заголовки в модуле.
Бен Легжеро,
178

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

Goto Framework -> Target -> Build Phases и перетащите соответствующие файлы заголовков из Project в Public. Надеюсь, это поможет!

Снимок экрана

Лонг Фам
источник
4
Это помогло мне включить код Objective C в структуру Swift, спасибо!
Вадим
1
Вы также можете внести это изменение в «Целевое членство с проекта на общедоступное» в своем файле, используя окно инспектора файлов в правой части главного экрана XCode.
Pigpocket
Если вы импортируете библиотеку в сочетание swift / objc, необходимо убедиться, что заголовок моста также является общедоступным. Я сделал ошибку!
Ник H247,
75

Вы можете установить для параметра Разрешить немодульные включения в модулях платформы в настройках сборки для затронутой цели значение ДА. Это параметр сборки, который вам нужно изменить:

Элемент настроек сборки, который нужно отредактировать

ПРИМЕЧАНИЕ . Вы должны использовать эту функцию, чтобы обнаружить основную ошибку, которая, как я обнаружил, часто вызывается дублированием глобальных включений в угловых скобках в файлах с некоторыми зависимыми отношениями, то есть:

#import <Foo/Bar.h> // referred to in two or more dependent files

Если установка « Разрешить немодульные включения в модули фрейма» на « ДА» приводит к набору ошибок типа «X - неоднозначная ссылка» или чего-то в этом роде, вы сможете отследить нарушающие дубликаты и устранить их. После того, как вы очистили свой код, установите для параметра Разрешить немодульные включения в модулях фрейма значение НЕТ .

Revprez
источник
1
Ладно, проблема в угловых скобках! У меня была эта проблема с импортом CocoaPods, и я исправил ее, изменив импорт, чтобы использовать кавычки вместо угловых скобок.
Майкл Форрест
Ой, нет. Обнаружил, что он сломался после того, как я очистил свой проект: - /
Майкл Форрест
2
Я не могу найти никаких предупреждений о "неоднозначной ссылке". Каковы недостатки установки ДА ?
Николас Миари
33

У меня была такая же проблема, и я решил ее, просто опубликовав файл заголовка. [проблема]

Если вы работаете над несколькими модулями в своем проекте. Затем ваш файл заголовка должен быть общедоступным, чтобы его можно было использовать в других частях проектов. Что вам нужно, так это выбрать этот файл заголовка и в представлении служебных программ проекта. Измените файл с Project / Private на Public. См. Изображение ниже:

Изменение области файла заголовка

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

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

Когда вы получаете эту ошибку, решение в некоторых случаях может заключаться в том, чтобы просто пометить файл, который вы пытаетесь импортировать, как «общедоступный» в инспекторе файлов «Целевое членство». По умолчанию это «Проект», и при такой настройке это может вызвать эту ошибку. Так было со мной, например, когда я пытался импортировать заголовки Google Analytic во фреймворк.

Джон Бушнелл
источник
1
Этот ответ очень помог мне в моей аналогичной проблеме. Я не знал, что файлы заголовков фреймворка можно добавить к цели. В проектах приложений заголовки никогда не являются частью цели.
биография,
21

На самом деле, более простой способ исправить это - вместо этого переместить #importоператор в начало .mфайла (вместо того, чтобы помещать его в файл .hзаголовка). Таким образом, он не будет жаловаться на то, что включает немодульный заголовочный файл. У меня была эта проблема , когда Allow non-module includesустановлен в YESсделал НЕ работать для меня, так что , перемещая его в файл реализации, он перестал жаловаться. Фактически, это предпочтительный способ импорта и включения файлов заголовков. После того, как вы это сделаете, верните это значение в NOрабочее состояние.

В идеале мы должны стремиться к тому, чтобы Allow non-module includesначать NO. Установка этого значения YESв большинстве случаев означает, что вы делаете что-то не так. Параметр переводится как «Разрешить импорт случайных файлов заголовков на диск, которые не являются частью модуля». На практике это применимо к очень немногим случаям использования, поэтому этот параметр должен быть всегда NO(т.е. значение по умолчанию).

странные времена
источник
11

Если вы разрабатываете свой собственный фреймворк:

Почему это происходит?

Если в каком-либо из общедоступных файлов заголовков, которые вы упомянули в своем module.modulemap, есть операторы импорта, которые не упомянуты в modulemap, это приведет к ошибке. Поскольку он пытается импортировать какой-либо заголовок, который не объявлен как модульный (в module.modulemap), он нарушает модульность фреймворка.

КАК я могу это исправить?

Просто включите заголовок, который вызвал ошибку, в ваш module.modulemap и выполните сборку снова!

ПОЧЕМУ НЕ просто установите allow non-modular на YES?

Поскольку на самом деле это не совсем решение, вы говорите своему проекту: «Этот фреймворк должен был быть модульным, но это не так. Используйте его как-нибудь, мне все равно». Это не решает проблему модульности вашей библиотеки.

Для получения дополнительной информации проверьте это сообщение в блоге или обратитесь к документации clang .

Мерт Челик
источник
как вы настроили module.modulemap с фреймворком проектов какао, я попытался разрешить моей библиотеке работать с проектами только для Swift, но поскольку одна зависимость библиотеки, module.modulemap, не работает, cocoapod автогенерация карты модулей, но, похоже, не работает, сталкивались ли вы с чем-то подобным?
Амадеу Кавальканте Филью
10

Allow Non-modular Includes in Framework Modulesработает только в коде objc. не работать в быстром темпе.

После периода исследований я обнаружил, что swift может передавать параметр предупреждения в clang, поэтому установите OTHER_SWIFT_FLAGSзначение-Xcc -Wno-error=non-modular-include-in-framework-module предотвращения ошибки быстрого импорта.

только для тех, у кого такая же проблема

SolaWing
источник
8

Если вам это нужно для целей CocoaPods, добавьте эти строки в Podfile:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      target.build_settings(config.name)['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
    end
  end
end
k06a
источник
6

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

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

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

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

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

июна
источник
6

та же проблема сводит с ума. наконец, я обнаружил, что в реализации вместо интерфейса можно добавить 'import xxx.h'. И если вы используете Cocoapods для управления своим проектом. вы можете добавить

s.user_target_xcconfig = {'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'ДА'}

в вашем файле xxx.podspec.

贺彦文
источник
6

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

#import "MyFile.h"

а не как #import <MyFramework/MyFile.h>.

Миша Карпенко
источник
2

Я тоже столкнулся с этой проблемой и первоначально думал, что это проблема CocoaPods, но это была проблема в настройках сборки приложений, где кто-то (возможно, я) установил ${PODS_ROOT}пути поиска заголовков и установил его как recursiveпоиск. Это позволяло ему находить заголовки, которые не были предназначены для использования при создании приложения. Как только я настроил это на использование, non-recursiveвсе было в порядке. использование recursiveпоиска - ужасный прием, пытающийся найти правильные заголовки. Урок выучен.

Ucangetit
источник
Могу подтвердить, что это тоже была моя проблема.
Уилсон Муньос
У меня была эта проблема с PersonalizedAdConsent, и это устранило ее. Благодарность!
Стивен Эллиотт
1

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

Грег
источник
0

Я закончил тем, что переместил Umbrella Header в конец списка заголовков после проверки вышеуказанных решений, и это сработало в Xcode 9.3.

альфватт
источник
0

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

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

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

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

Виттал Пай
источник
0

В моем случае я забыл добавить файлы .h и .m в раздел «s.source_files» файла .podspecs.

после добавления этого в него все работает нормально.

введите описание изображения здесь

Мухаммад Ахмед Байг
источник
0

попробуй @import FrameworkNameвместо#import "FrameworkName.h"

Кэ Ян
источник
0

У меня была аналогичная проблема! При запуске моего целевого приложения все работало нормально, но при переходе к тестовой цели и попытке запустить тесты выскакивала ошибка «Включить немодульный заголовок внутри модуля фреймворка». Я попробовал все решения, размещенные здесь, но ни одно из них не сработало. В конце я прокрутил все настройки сборки и прочитал описание каждой из них, относящейся к заголовкам.

Переключение USE_HEADERMAPна NOсделал трюк!

Я надеюсь, что это будет полезно для всех!

Игнасио Мариани
источник
-6

Мне удалось устранить десятки этих ошибок с помощью Git clean. Вот команда: git clean -dffx && git reset --hard

Мэтт Беарсон
источник
Это спасло мне день!
pilcrowpipe