Error del compilador Swift: "encabezado no modular dentro del módulo de marco"
Ahora me gustaría migrar mi marco ObjC a Swift y recibí el siguiente error:
include of non-modular header inside framework module 'SOGraphDB'
Las referencias son a un archivo de encabezado que simplemente define un protocolo y uso este archivo de encabezado en algunas clases para usar este protocolo.
Parece estar relacionado con la función del módulo, pero por el momento no está muy claro cómo solucionarlo. ¿Conoce alguna solución?
ACTUALIZAR:
Este es un error del compilador Swift.
ACTUALIZACIÓN 2:
Una solución rápida (pero que no resuelve la causa raíz) es establecer la siguiente configuración en sí: CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES
¿Tu encabezado es público?
Seleccione el archivo de encabezado en el explorador de proyectos. Luego, en la sección de la derecha en xcode, notarás que hay un menú desplegable al lado del objetivo. Cambie eso de "proyecto" a "público". Esto funcionó para mí.
Este es un comportamiento esperado del compilador y por una muy buena razón.
Creo que la mayoría de las personas que se encuentran con estos problemas se deben a que cambian de Application Target
a Framework Target
y comienzan a agregar encabezados C y Objective C en el encabezado general del marco , esperando que tenga el mismo comportamiento que el Bridging Header de la aplicación , que se comporta de manera diferente. El encabezado general en realidad está designado para un marco obj-c mixto y rápido y su propósito es exponer las API al mundo exterior que su marco tiene en Objective-C o C. Eso significa que los encabezados que coloquemos allí deberían ser de ámbito público.
No debe usarse como un lugar que expone encabezados Objective-C/C que no son parte de su marco al código rápido de su marco. Porque en ese caso estos encabezados también estarán expuestos como parte de nuestro módulo de marco al mundo exterior, lo que a menudo no es lo que queremos hacer ya que rompe la modularidad. (Y esa es exactamente la razón por la que el valor predeterminado de Permitir inclusiones no modulares en módulos de marco es NO )
Para exponer la biblioteca Objective-C/C al código rápido de su marco, debemos definir un módulo rápido separado para dicha biblioteca. Entonces import YourLegacyLibrary
se puede utilizar un vencejo estándar.
Permítanme demostrar esto en un escenario típico: integrarlo libxml2
en nuestro marco.
1. Primero necesitas crear un module.modulemap
archivo que tendría este aspecto:
Para el marco OSX:
module SwiftLibXML2 [system] {
header "/usr/include/libxml2/libxml/xpath.h"
export *
}
Para el marco de iOS:
module SwiftLibXML2 [system] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/libxml2/libxml/xpath.h"
export *
}
Todo lo que hace es envolver el encabezado y cualquier otro encabezado al que haga referencia dentro del módulo swift, de modo que swift pueda generar los enlaces rápidos para estas interfaces C.
2. Luego, en el directorio de su proyecto xcode, cree una carpeta SwiftLibXML2
y coloque este module.modulemap allí.
3. En Configuración de compilación , agregue $(SDKROOT)/usr/include/libxml2
a Rutas de búsqueda de encabezado
4. En Configuración de compilación , agregue $(SRCROOT)/SwiftLibXML2
a Rutas de importación
5. En la pestaña General del proyecto , agréguelo libxml2.tbd
a Bibliotecas y marcos vinculados .
Ahora importa este módulo donde sea necesario con:
import SwiftLibXML2
(si desea ver un ejemplo de module.map más completo, sugeriría hacer referencia al module.modulemap de Darwin en /usr/include/module.modulemap
, necesitaría tener instaladas las herramientas de línea de comandos de Xcode para ir allí, consulte Missing /usr/include en OS X El Capitan )
A continuación se explica cómo aplicar automáticamente la solución rápida para que no tenga que cambiarla Pods.xcodeproj
manualmente después de cada una pod install
.
Agregue este fragmento al final de su 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
La solución para mí fue ir al objetivo-> configuración de compilación-> ¡Permitir inclusiones no modulares en los módulos del marco cambiar a SÍ!