wake-up-neo.net

Swift-Compiler-Fehler: "Nicht-modularer Header im Rahmenmodul"

Nun möchte ich mein ObjC-Framework zu Swift migrieren und habe folgende Fehlermeldung erhalten:

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

Die Verweise beziehen sich auf eine Header-Datei, die nur ein Protokoll definiert, und ich verwende diese Header-Datei in einigen Klassen, um dieses Protokoll zu verwenden.

Ist anscheinend mit der Modul-Funktion verbunden, aber es ist im Moment nicht ganz klar, wie sie repariert werden soll. Kennen Sie eine Lösung?

AKTUALISIEREN:

Dies ist ein Swift-Compiler-Fehler.

UPDATE 2:

Eine schnelle Lösung (ohne Behebung der eigentlichen Ursache) besteht darin, die folgende Einstellung auf yes zu setzen: CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES

190
Stephan

Ist dein Header öffentlich?

Wählen Sie die Header-Datei im Projekt-Explorer aus. In dem Abschnitt rechts in xcode sehen Sie dann eine Dropdown-Liste neben dem Ziel. Ändern Sie das von "Projekt" in "Öffentlich". Das hat bei mir funktioniert.

public header

293
kgreenek

Dies ist ein erwartetes Compilerverhalten und das aus einem sehr guten Grund.

Ich denke, die Mehrheit der Leute, die auf dieses Problem stoßen, wird verursacht, nachdem sie von Application Target Zu Framework Target Gewechselt sind und C- und Objective C-Header in den Umbrella-Header des Frameworks eingefügt haben Erwarten, dass es dasselbe Verhalten hat wie Bridging Header der Anwendung, das sich anders verhält. Der Umbrella-Header ist eigentlich für ein gemischtes Swift-, obj-c-Framework vorgesehen, und sein Zweck besteht darin, die APIs der Außenwelt zugänglich zu machen, die Ihr Framework in Objective-c oder C hat. Das heißt, die Überschriften, die wir dort platzieren, sollten im öffentlichen Bereich liegen.

Es sollte nicht als Stelle verwendet werden, an der Objective-C/C-Header, die nicht Teil Ihres Frameworks sind, im Swift-Code Ihres Frameworks angezeigt werden. Denn in diesem Fall werden diese Header auch als Teil unseres Framework-Moduls der Außenwelt ausgesetzt. Dies ist häufig nicht das, was wir tun möchten, da es die Modularität aufhebt. (Und das ist genau der Grund, warum Nicht modulare Includes in Framework-Modulen zulässt standardmäßig [~ # ~] no [~ # ~])

Um die Objective-C/C-Bibliothek Ihrem Framework-Code Swift zugänglich zu machen, sollten wir ein separates Modul Swift für diese Bibliothek definieren. Dann kann ein Standard Swift import YourLegacyLibrary Verwendet werden.

Lassen Sie mich dies an einem typischen Szenario demonstrieren: Einbettung von libxml2 In unser Framework.

1. Zuerst müssen Sie eine module.modulemap - Datei erstellen, die folgendermaßen aussehen würde:

Für OSX-Framework:

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

Für iOS Framework:

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

Alles, was es tut, ist, dass es den Header und alle anderen Header, auf die es verweist, innerhalb des Moduls Swift umschließt, sodass Swift dann die Bindungen Swift generieren kann für diese C-Schnittstellen.

2. Erstellen Sie dann in Ihrem xcode-Projektverzeichnis einen Ordner SwiftLibXML2 Und platzieren Sie diese module.modulemap dort

3. Fügen Sie in Build Settings$(SDKROOT)/usr/include/libxml2 zu Header Search Paths hinzu

4. Fügen Sie in Build Settings$(SRCROOT)/SwiftLibXML2 zu Import Paths hinzu

5. Fügen Sie auf der Registerkarte Allgemein des Projekts libxml2.tbd Zu Verknüpfte Frameworks und Bibliotheken hinzu.

Jetzt importieren Sie dieses Modul wo nötig mit:

import SwiftLibXML2

(Wenn Sie ein vollständigeres module.map-Beispiel sehen möchten, würde ich vorschlagen, Darwins module.modulemap unter /usr/include/module.modulemap zu referenzieren. Dazu müssen Xcode-Befehlszeilentools installiert sein. reference Fehlende/usr/include in OS X El Capitan )

123
ambientlight

So wenden Sie den Quick Fix automatisch an, damit Sie Pods.xcodeproj nicht manuell nach jedem pod install ändern müssen.

Fügen Sie dieses Snippet am Ende Ihrer Pod-Datei hinzu:

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
53
funroll

Lösung für mich war zu gehen auf target-> build settings-> Erlaube nicht modulare Includes in Framework Modules auf JA wechseln

29
Vlad Burlaciuc

In Swift :

1. Ändern Sie Ihr Xcode-Projekt und die Build-Einstellungen Ihrer Ziele wie folgt:

Nicht modulare Einschlüsse in Framework-Modulen zulassen: Nein

Bitcode aktivieren: Ja

2. Verwenden Sie die aktuellste Version, die für GoogleMaps iOS SDK verfügbar ist (verwenden Sie CocoaPods, um es zu erhalten):

GoogleMaps (1.10.4)

3. Kommentiere den problematischen Import:

//import GoogleMaps

4. Erstellen oder ändern Sie Ihre Bridging-Header-Datei und fügen Sie den problematischen Import hinzu:

[Ihr Xcode-Projektname] -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. Reinige und baue dein Xcode-Projekt neu auf.

15
King-Wizard

Ich glaube, ich bin damit umgekommen. Ich habe einen Modellcode, der sqlite3 in einem Framework verwendet. In meinem Fall war der Schuldige <sqlite3.h>.

Das Problem war, dass ich in meinem Header "Module/Module.h" einen öffentlichen Header importierte, der <sqlite3.h> importierte. Die Lösung bestand darin, alle sqlite3_xxx-Typen auszublenden und sicherzustellen, dass sie in keiner öffentlichen .h sichtbar waren. Alle direkten Verweise auf sqlite3 wurden als privat oder für das Projekt sichtbar gemacht. Zum Beispiel hatte ich ein öffentliches Singleton, an dem einige sqlite3_stmt-Zeiger hängen. Ich habe diese in eine separate Klasse verschoben, die jetzt nur noch eine Vorwärtsdeklaration in diesem öffentlichen Header ist. Jetzt kann ich bauen.

Die Einstellung CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES funktionierte übrigens nicht. Ich habe versucht, es sowohl im Rahmen als auch im abhängigen Projekt festzulegen. Diese Problemumgehung war notwendig, obwohl ich nicht sicher bin, warum.

15
Jimmy Dee

Diese Antwort ist veraltet.

Beim Importieren von Frameworks müssen Sie alle Header-Dateien / die Abhängigkeiten mit dem Stammheader gemeinsam nutzen. Der einfachste Weg, um sicherzustellen, dass dies immer funktioniert, ist das Importieren aller Header im Ordner "Headers" des Frameworks in den Pfad der öffentlichen Header.

enter image description here

Der Swift-Compiler erstellt anhand dieser Informationen eine Karte mit nicht verknüpften Symbolen und den zugehörigen Typinformationen.

5
seo

Die Header-Datei wurde dem Ziel zugewiesen, aber nur als sichtbares Projekt markiert. Eine Änderung der öffentlichen Umgebung führt zur Behebung dieses Fehlers.

3
Stephan

Nicht

#import "MyOtherFramework.h"

Tun

#import <MyOtherFramework/MyOtherFramework.h>
3
hfossli

Ich weiß, dass dies eine alte Frage ist, aber ich hatte das gleiche Problem und nichts von oben hat mir geholfen. Ich hoffe, meine Antwort wird für jemanden hilfreich sein. In meinem Fall war das Problem in der Einstellung ALWAYS_SEARCH_USER_PATHS. Als es auf NO eingestellt war, wurde das Projekt gebaut und funktionierte einwandfrei. Soweit es für eine der Pods jedoch erforderlich war, dass sie auf JA gesetzt wurde, erhielt ich einen Fehler 

Include eines nicht modularen Headers innerhalb des Framework-Moduls

Nach ein paar Tassen Kaffee und den ganzen Tag recherchierte ich heraus, dass die bekannten Versionshinweise von Xcode 7.1 Beta 2 :

• Wenn Sie eine Fehlermeldung erhalten, die angibt, dass "nicht-modulare Header im Rahmenmodul enthalten" für ein .__ enthalten ist. Stellen Sie sicher, dass das Framework, das zuvor kompiliert wurde, "Always Search User Paths" Build-Einstellung ist auf "Nein" gesetzt. Der Standardwert ist "Ja" nur aus Gründen des Altlasten. (22784786)

Ich habe zwar XCode 7.3 verwendet, aber es scheint, dass der Fehler noch nicht behoben wurde.

2
iyuna

Ich möchte auch meine Erfahrung mit dem Problem hinzufügen.

Nur um es zusammenzufassen:

  • Die Antwort von @ ambientlight ist großartig und behebt die meisten Probleme.
  • das Ermöglichen nicht-modularer Header ist eine andere Lösung (siehe oben einige Antworten).
  • markieren Sie die Kopfzeilen des Frameworks als öffentlich (nur die, die Sie anzeigen möchten) und importieren Sie sie in die Kopfzeile.

Hier sind meine 2 Ergänzungen zu den obigen Antworten:

  • Überprüfen Sie die Importe in Ihrem Projekt sorgfältig auf Header, die Ihre Frameworks direkt in sie importieren (statt nach Möglichkeit die Forward-Deklaration zu verwenden). Es empfiehlt sich nicht, eine Header-Datei in eine andere Header-Datei aufzunehmen. Dies führt manchmal zu Problemen, da dies zu einem mehrfachen Einfügen eines Headers und zu Linkerproblemen führen kann, wenn er nicht ordnungsgemäß ausgeführt wird.
  • UPDATE: Stellen Sie sicher, dass die Architekturen der Bibliothek und des Ziels, das Sie verknüpfen möchten, übereinstimmen.
  • und schließlich, nachdem ich all das getan hatte, stieß ich immer noch auf diesen Fehler. Also habe ich ein wenig mehr gegraben und festgestellt (in den Apple-Entwicklerforen, aber ich habe den Link verloren :(), dass, wenn Sie die Kopfzeilen in den Umbrella-Header nicht wie diesen <framework/headerName.h> einfügen, sondern nur diesen "headerName.h", das Problem beseitigt.

Ich habe den letzten Versuch ausprobiert und bisher habe ich dieses Problem nicht mehr erlebt. Ich vermute jedoch, dass diese Lösung nur gültig ist, wenn Sie einige der Top-Antworten angewendet haben (Hinweis: Sie sind beispielsweise nicht alle miteinander kompatibel.) , der Modulansatz und das Ermöglichen eines nicht modularen Headers umfasst).

2

Umschalten Build-Einstellungen> Nicht modulare Einschlüsse in Framework Modules zulassen YES! löste dasselbe Problem für mich.

1
Mohamed TAIEB

Ich hatte genau dieses Problem, wenn ich mein eigenes Framework in ein Projekt einfügte. Behebung des Problems, indem alle Importe von sqlite3.h in .m-Dateien gespeichert wurden, die nicht in öffentlichen .h-Dateien waren. Ich gehe davon aus, dass andere Bibliotheken ähnliche Probleme mit Xcode kennzeichnen.

1
Rob Sanders

In meinem Fall (Xcode 9 Beta 6 - Swift 4 - mit Cocoapods) wurde dieses Problem gelöst, als ich Podfile.lock und das Verzeichnis Pods gelöscht und erneut pod install ausgeführt habe

1
m_katsifarakis

Ich habe dieses Problem bekommen, nachdem ich ein Projekt von Swift2 auf Swift3 aktualisiert habe. Ich habe XCode 8.3.2 zum Aktualisieren des Codes verwendet und konnte den Fehler "nicht modularer Header innerhalb des Rahmenmoduls" nicht beseitigen. Wenn ich dasselbe Projekt in einer anderen Version von XCode (Version 9.0.1) geöffnet habe, wurde der Fehler nicht angezeigt. 

1
DevB2F

Ich hatte das spezifische Problem mit Facebook 4.02 SDK und FBSDKCoreKit.

Ich habe alle Schritte gemacht, aber immer noch Fehler über nicht modulare Header. Ich habe nur den spezifischen Header per Drag & Drop aus dem Framework gezogen, um den Abschnitt phase-> header zu erstellen.

Dann wird automatisch eine Kopie der Kopfzeile im Projektnavigator oben erstellt.

Ich entfernte es aus den Buildphasen -> Header und löschte die neue Datei und funktionierte einwandfrei.

Wie es zurückgesetzt oder so.

1
Haris

In der Regel wird dieser Fehler durch die gewählte Antwort verursacht. Ich habe diesen Fehler jedoch einmal durch Zufall beim Ziehen von Framework-Dateien in meinen neuen Projektordner angezeigt. Ich klickte auf, um die Frameworks zu löschen, drückte jedoch versehentlich auf "Remove Reference" (Referenz entfernen), anstatt die Dateien vollständig zu löschen. Wenn ich jetzt meinen Projektordner im Finder öffnete, sah ich dort Dateien wie 'CoreLocation' und 'AudioToolbox'. Durch das Löschen dieser Dateien aus dem Projektordner und das Reinigen des Projekts wurde das Problem behoben.

0
ColossalChris

Nachdem Sie den Import nicht modularer Include-Elemente zugelassen haben, können Sie versuchen, dieses Modul mit dem Objective-C-Bridging-Header zu importieren:

#import <YandexMobileMetrica/YandexMobileMetrica.h>
0
Yuri Korshev

Ich habe das Problem gelöst, Modules Ordner aus dem Framework zu entfernen.

  • Navigieren Sie mit Finder zu Ihrem Standort im Framework, der im App-Projekt vorhanden ist 

  • Gehen Sie in den Test.framework-Ordner (In diesem Fall wird es SOGraphDB.framework sein) und den Modules-Ordner löschen. 

  • Reinigen und erneutes Erstellen der App, das Problem wird dadurch gelöst.

0
Vittal Pai