objective-c - logo - objective c vs swift
El encabezado Swift to Objective-C no se creĆ³ en Xcode 6 (30)
A veces, solo necesita desconectar y luego volver a establecer la membresía de destino en el archivo obj-c .m.
Recientemente he estado trabajando para agregar Swift a un proyecto existente, para probarlo de manera real.
Al agregar un archivo de origen de Swift al proyecto, no tengo problemas para obtener el "Encabezado de enlace", es decir, de Objective-C a Swift.
Pero el archivo de encabezado -Swift.h que se supone expone las clases Swift marcadas @objc o subclases de clases ObjC, no se encuentra en ninguna parte :-(
No veo ninguna instrucción específica sobre cómo llevar a cabo el uso de mi nueva subclase, escrita en Swift, en mi código de aplicación principal (que todavía es Obj-C).
La aplicación de la que soy desarrollador líder tiene una base de código bastante grande (70.000 líneas), por lo que la transición de una sola vez está fuera de discusión.
Ahora funciona.
- El proyecto debe tener un Nombre de módulo de producto que no incluya espacios.
- El módulo de Definiciones se debe establecer en Sí en Configuración de compilación, en Empaquetado.
Por fin funciona. Gracias a todos por la ayuda :-)
Aquí hay otra variación del módulo Nombre-Swift.h que no se está generando.
Decidí incluir Cartas de IOS en mi proyecto, pero no quería mezclar las fuentes en el mismo directorio, así que coloqué la carpeta de Proyectos de Cartas junto a la carpeta de proyectos de mi código. Arrastre el proyecto de gráficos a la barra de navegación de mi proyecto e incluí el marco en la lista de binarios integrados del objetivo de mi proyecto en la configuración general del proyecto y configuré el interruptor de código Swift que contiene contenido incrustado en la pestaña Configuración de compilación de mi proyecto en la sección Opciones de compilación .
El archivo moduleName-Swift.h de mi proyecto nunca se generaría sin importar qué otros modificadores o configuraciones se sugieran aquí. Finalmente, utilizando el método de Lou Z para buscar los archivos -Swift.h, vi que se estaba generando un archivo Charts-Swift.h en el directorio de compilación xcode de mi proyecto en Charts.framework / Headers /
La solución para usar el paquete Swift de ios-charts de Daniel Gindi sin incluir el código en el directorio de origen de mi proyecto fue agregar:
#import "Charts/Charts-Swift.h"
A los módulos que grafican los datos de mi proyecto.
Descubrí que tenía que corregir todos los errores de compilación antes de que generara el archivo.
El problema para mí fue que se trataba de un problema de gallina / huevo, ya que no vi ningún error de compilación hasta que en realidad comenté la declaración de #import
:
//#import "ProductModuleName-Swift.h"
que reveló un montón de otros errores en mi código Swift.
Una vez que arreglé estos nuevos errores y obtuve la creación de la fuente con éxito, ¡no comenté el #import
and bingo! El encabezado fue creado e importando correctamente :)
El nombre del archivo siempre va precedido por su nombre de destino . Se denomina nombre del producto, pero prácticamente es el nombre del objetivo. Por lo tanto, si desea que se compile para un nuevo destino, esté preparado para esperar ese that_target-Swift.h
.
Una forma de manejar esto es
- Agregue un preprocesador para cada uno de sus objetivos que sea el nombre de su propio destino (sin espacios). Ex.
MY_TARGET=1
. Agregue esto en Configuración de proyecto-> Configuración de compilación-> Macros de preprocesador para cada uno de sus objetivos. - Si está utilizando un archivo PCH,
Añade estas líneas en el archivo PCH
#if MY_TARGET==1
#include "My_Target-Swift.h"
#elif THAT_TARGET==1
#include "That_Target-Swift.h"
#endif
La ventaja de usar el archivo PCH es que no tiene que incluir los encabezados en todas partes.
- Si no está utilizando un archivo PCH, simplemente agregue estas mismas líneas en un solo encabezado e incluya ese encabezado donde necesite usar las clases swift.
Esto debería funcionar bien.
El proyecto debe tener un nombre de módulo que no incluya espacios. El módulo de Definiciones se debe establecer en Sí en Configuración de compilación, en Empaquetado. comentó la declaración #import:
Si aún tiene un error al importar "ProductModuleName-Swift.h", entonces
// # import "ProductModuleName-Swift.h"
que reveló un montón de otros errores en mi código Swift.
Una vez que arreglé estos nuevos errores y obtuve la creación de la fuente con éxito, ¡no comenté el #import and bingo! El encabezado fue creado e importando correctamente :)
En mi caso, tuve que establecer el destino de la implementación al menos en "OS X 10.9" y el encabezado -Swift.h
se generó automáticamente. Tenga en cuenta que puede recibir muchas advertencias de desaprobación cuando cambia la versión de destino de la implementación, especialmente cuando tiene una base de código Objective C más antigua y muy grande. En nuestro caso, también tuvimos mucho trabajo por hacer en archivos XIB y ver clases.
Encontré esta solución
- Crear SwiftBridge.h
- poner #import "ProductModuleName-Swift.h"
- Haga público este archivo .h (importante) Seleccione el archivo -> En Mostrar el archivo Inspector (barra derecha) -> Hágalo público
Ahora usted puede
#import "SwiftBridge.h"
en lugar de ProductModuleName-Swift.h
Esta es una solución alternativa, para la próxima versión de Xcode, creo que este problema se resolverá. Buena suerte
Encontré un truco que siempre me funciona.
- Cree su #import "ProductModuleName-Swift.h" en su archivo appDelegate.h y en su archivo ProductName-Prefix.pch. Si no lo tiene en xcode 6, puede crearlo de esta manera. ¿Por qué ProjectName-Prefix.pch no se crea automáticamente en Xcode 6?
- Command + shift + k para limpiar su código, si recibe un error sobre su "ProductModuleName-Swift.h", elimínelo del archivo appDelegate.h.
- Limpia tu código de nuevo. Ahora todo funcionará a la perfección.
- Si recibe nuevamente el error sobre el "ProductModuleName-Swift.h", ahora cree nuevamente en el archivo appDelegate.h y limpie su código nuevamente.
Haga este trabajo (elimine y cree el "ProductModuleName-Swift.h" del archivo appDelegate.h y limpie su código) cada vez que reciba este error para silenciarlo.
Esta respuesta aborda el caso de uso donde es posible que ya tenga algún código Objective-C que llame a las clases de Swift y luego comience a recibir este error.
Cómo solucionar el problema
Los siguientes pasos finalmente resolvieron todos los problemas para mí. Leí arriba a alguien que menciona el "huevo y la gallina" y es exactamente ese concepto el que me llevó a este procedimiento. Este proceso explícito muestra que uno tiene que eliminar cualquier código de Objective-C que haga referencia a las clases de Swift hasta que se genere el encabezado.
- Comente la declaración #import "ProductModuleName-Swift.h" en su archivo de implementación de Objective-C
- Comente cualquier referencia en el archivo de implementación de Objective-C a Swift Classes
- Limpiar y construir
- Resolver todos los errores / advertencias
- Elimine el comentario en la declaración #import "ProductModuleName-Swift.h"
- Limpie y genere (con éxito o corrija los errores restantes, verifique que no esté haciendo referencia a ninguna clase Swift en Objective-C en este momento . Si es así, coméntelos temporalmente)
- Verifique que "ProductModuleName-Swift.h" se genere con Cmd-Clicking en el nombre de clase de la declaración #import "ProductModuleName-Swift.h"
- Elimine el comentario sobre el código que hace referencia a las clases de Swift en el archivo de implementación de Objective-C.
- Limpie y genere de manera normal (debe generarse el "ProductModuleName-Swift.h" y su código de Objective-C que hace referencia a Swift Classes se puede usar normalmente)
Nota Bene: las respuestas sobre el cambio de espacios a guiones bajos y el Módulo de Definiciones a SÍ como se indicó anteriormente todavía se aplican al realizar este proceso, al igual que las reglas especificadas en la Documentación de Apple .
Puente de camino de encabezado
En un error, el archivo ProductModuleName-Bridging-Header.h no se encontró durante el proceso de compilación. Este hecho generó un error.
<desconocido>: 0: error: puente de cabecera ''/Users/Shared/Working/abc/abc-Bridging-Header.h'' no existe
Una inspección más cercana del error indicó que el archivo nunca existiría en la ubicación descrita porque en realidad estaba ubicado en ( una ruta incorrecta )
''/Users/Shared/Working/abc/abc/abc-Bridging-Header.h''. una búsqueda rápida de la configuración de compilación de destino / proyectos para realizar la corrección manualmente y el archivo abc-Swift.h se generó de nuevo automáticamente.
Este puede ser un punto obvio (quizás demasiado obvio), pero debe tener al menos un archivo swift en el proyecto para que el encabezado lo genere. Si está escribiendo boilerplate o código de configuración con la intención de escribir swift más tarde, la importación no funcionará.
Lo más importante es que este archivo es invisible !!! Al menos está en Xcode6 beta5. No habrá ningún archivo llamado "YourModule-Swift.h" en su área de trabajo. Solo asegúrese de tener el nombre del módulo y el módulo definido como sí, y utilícelo en su clase de Objective-C.
Me estaba costando mucho determinar la importancia de los encabezados de swift en el nombre de mi módulo / objetivo-c. También leí muchos artículos aquí.
Pero la respuesta definitiva para el nombre de su proyecto con todos sus caracteres especiales incluidos (ya sea ''.'' O un número o un espacio), puede encontrar el texto que le funcionará en el " Nombre del módulo del producto " en la Configuración de compilación del objetivo. .
Por ejemplo, mi nombre de destino comenzó con un número - "1mg" y el campo mencionado anteriormente mostraba "_mg" como el nombre de mi módulo.
así que utilicé #import "_mg-Swift.h" y funcionó.
Ok, aquí están todas las cosas que realmente necesitas!
1.Elimine todos los archivos swift que haya agregado y compile el código sin errores.
----------
----------
2. Vaya a la configuración de compilación "Proyectos" y establezca el nombre del módulo del producto. El proyecto debe tener un Nombre de módulo de producto que no incluya espacios.
----------
----------
3.Define el módulo debe configurarse en Sí en la configuración de compilación, en Empaquetado, en su proyecto, ¡y no en el objetivo!
----------
----------
4. Ahora cree un archivo swift o un controlador de vista, en archivo-> nuevoArchivo->
----------
----------
Se le pedirá que cree un encabezado puente, le permite hacer uno. Si lo ha rechazado una vez, deberá agregar manualmente un -Bridging-Header.h
5. Agregue @objc en el controlador, para decirle al compilador que hay algún archivo swift, que debe ser expuesto a ObjectiveC
----------
----------
6. Construya el proyecto e importe #import "-Swift.h" en cualquiera de los controladores objectC, ¡y funcionará! ¡Puedes Comando-clic en él para ver el archivo real!
----------
----------
¡Espero que esto ayude!
Permítame compartir mis experiencias tratando de usar Swift en un antiguo proyecto de objc. No tuve que configurar el Defines module
en YES
.
En mi caso, necesitaba asegurarme manualmente de que había un encabezado de puente objc. Solo el nombre del encabezado de la interfaz generado estaba presente en mi configuración de compilación.
Esto llevó a que se generara un archivo MyApp-Swift.h, pero sin ningún rastro de mis clases de Swift.
La documentación de Apple dice que se le pedirá que cree un encabezado puente cuando agregue su primer archivo swift. Bueno, no lo era. MyApp-Bridging-header.h
manualmente un archivo MyApp-Bridging-header.h
y lo señalé en el campo "Cabecera de puente de Objective-C". Eso hizo que mi archivo MyApp-Swift.h se llenara con mis clases de Swift.
Quería agregar una razón más por la que podría encontrar un problema con esto: estaba creando un marco que mezclaba el código de Swift y Objective-C. No pude importar las clases Swift fuera del marco. Revisé el archivo -Swift.h y se estaba generando pero estaba vacío.
El problema resultó ser muy, muy simple: ¡no había declarado que ninguna de mis clases de Swift fuera pública! Tan pronto como agregué la palabra clave pública a las clases, pude usarlas desde clases dentro y fuera del marco.
También es de destacar que dentro del marco (dentro de los archivos .m solo como lo menciona otra respuesta) tuve que importar el archivo -Swift.h como:
#import <FrameworkName/FrameworkName-Swift.h>
Segundando lo que mucha gente tiene aquí, pero agregando una captura de pantalla pertinente. Los códigos Swift y Obj-C ciertamente pueden vivir juntos. No es un juego de todo o nada.
Para acceder a los archivos de Swift en su Objective-C, todo lo que necesita hacer es agregar esta llamada a su archivo Obj-C (en el archivo .m / implementación):
#import "{product_module_name}-Swift.h"
(Donde {product_module_name} representa el nombre del módulo del producto de su proyecto). En lugar de tratar de adivinar el nombre de su módulo de producto o descubrir casos de esquina con espacios y caracteres especiales, solo vaya a la pestaña de configuración de compilación en el proyecto y escriba "nombre de módulo de producto"; el inspector le revelará la suya. Lo mío era algo que no esperaba que fuera. Echa un vistazo a esta captura de pantalla si estás confundido.
Y para que el código Obj-c funcione en Swift, solo necesitas agregar un archivo de encabezado puente e importar los encabezados Obj-C relevantes allí.
Si XCode está generando realmente su encabezado -Swift.h (en el interior de DerivedData) pero no se refiere a sus clases de Swift, asegúrese de que también tenga un encabezado puente definido. La forma en que leí los documentos implicaba que solo necesitaba eso para llamar a Objective-C desde Swift, pero también parece ser necesario para llamar a Swift desde Objective-C.
Vea mi respuesta: https://.com/a/27972946/337392
EDITAR: Es debido a los modificadores de acceso público vs. interno, como eventualmente encontré explicado en los documentos de Apple:
De forma predeterminada, el encabezado generado contiene interfaces para las declaraciones Swift marcadas con el modificador público. También contiene los marcados con el modificador interno si su destino de aplicación tiene un encabezado de puente de Objective-C.
Si el nombre del módulo de su proyecto tiene espacios, debe reemplazar los espacios con un guión bajo.
Por ejemplo, si el nombre de su proyecto es "Mi proyecto", usaría:
#import "My_Project-Swift.h"
Si eres como yo, probablemente tienes el nombre del encabezado equivocado. Después de golpearme la cabeza por un tiempo, busqué el archivo en DerivedData y estoy seguro de que está allí. En mi configuración (utilizando la carpeta de datos derivados estándar, creo):
cd ~/Library/Developer/Xcode/DerivedData
find * -iname ''*Swift.h''
Lo encontrara Si nada en esa carpeta coincide, entonces Xcode no lo genera.
Estoy usando Xcode versión 6.2 (6C86e)
Si está utilizando algo como Cocoapods (y está trabajando fuera del área de trabajo en lugar del proyecto), intente abrir el proyecto y compilarlo antes de abrir el área de trabajo y construir. YMMV.
Si pudo generar un proyecto anteriormente, sin problemas relacionados con “ProductModuleName-Swift.h” not found
error, y ahora está recibiendo nuevamente esos errores desagradables, la razón podría estar en sus cambios recientes.
Para mí esto fue por codificación de archivo .swift
incorrecta (accidental). Revertir cambios y traer el respaldo manualmente, hace el trabajo.
Solo un aviso para cualquiera que usó "." allí nombre del proyecto. Xcode reemplazará el "." con un guión bajo "_" para la versión Swift del archivo de encabezado de puente. Por extraño que parezca, el Bridging-Header.h que se genera no reemplaza los puntos con guiones bajos.
Por ejemplo, un proyecto con el nombre My.Project tendría los siguientes nombres de archivo de encabezado de enlace.
Bridging-Header.h (Autogenerado)
My.Project-Bridging-Header.h
Swift.h
Mi_Proyecto.h
Espero que esto ayude a cualquiera que haya usado un período y haya quedado atrapado como yo. Este archivo se puede encontrar en la siguiente ubicación.
Macintosh HD / Users / user /Library/Developer/Xcode/DerivedData/My.Project-fntdulwpbhbbzdbyrkhanemcrfil/Build/Intermediates/My.Project.build/Debug-iphonesimulator/My.Project.build/DerivedSources
Cuídate,
Jon
Tienes que importar un encabezado en las clases de Objective-C, que es:
#import “ProductModuleName-Swift.h”
Se genera automáticamente, en la referencia dice "Cualquier archivo Swift en su destino será visible en los archivos .m de Objective-C que contienen esta declaración de importación".
Tuve que eliminar el código swift de WatchOS2 de mi proyecto de Objective C. Y solo después de eso XCode ofreció generar -Swift.h
Tuve un problema similar y encontré que solo puedes agregar
#import “ProductModuleName-Swift.h”
para archivos obj-c .m, no archivos .h para el encabezado de sombrilla que se encuentra
Tuve un problema similar, pero mi proyecto se estaba compilando antes y de repente se produjo un error después de que algunos archivos cambiaran de código. Me tomó un tiempo averiguar por qué obtengo el error ''Archivo no encontrado'' para el archivo myproject-swift.h. Los cambios de código que había hecho tenían algunos errores. Xcode no apuntó a poner esos errores en lugar de todo el tiempo mostrando el ''Error de archivo no encontrado''. Luego obtuve una copia del código de la versión anterior y lo comparé con el nuevo código y combiné el archivo uno por uno. Después de cada fusión de archivos, se cumplió el proyecto para encontrar el error. Por lo tanto, la conclusión es si tiene un error en su código Xcode puede mostrar "error de archivo no encontrado" para el archivo myproject-swift.h. Lo más probable es que tengas un error de compilación en tu proyecto. Limpia esos errores y funcionará.
Yo tuve el mismo problema. Parece que tiene que ajustar la configuración (Define Module and Product Module Name) antes de agregar su primer archivo Swift.
Si lo hace después, el archivo "* -Swift.h" no se generará para este proyecto, incluso si agrega más archivos Swift o elimina el archivo Swift y crea uno nuevo.
* Lo único importante es: *
para utilizar el "Nombre del módulo del producto" definido en el destino, seguido de -Swift.h
#import <Product Module Name>-Swift.h
// in each ObjectiveC .m file having to use swift classes
// no matter in which swift files these classes sit.
No importa si el parámetro "Definir módulo" está configurado en Sí o No o si el Proyecto "Nombre del módulo del producto" no está configurado.
Recordatorio: las clases Swift deben derivarse de NSObject o haber sido etiquetadas con el atributo @objc para estar expuestas a ObjectiveC / Foundation || Cacao ...
No se crea un archivo real en el proyecto ([ProductModuleName] -Swift.h). Cmd + Click en la importación lo genera sobre la marcha (y en la memoria) para que pueda ver cómo se realiza el enlace, o abre un archivo en algún lugar en algún directorio de caché de Xcode, pero no está en el directorio del proyecto.
Debe configurar la propuesta de proyecto Defines Module (en la configuración de construcción del objetivo) en Sí y si el nombre de su módulo tiene espacios o guiones, use _ en todas las importaciones del archivo [ProductModuleName] -Swift.h.
Puede importarlo en todos los archivos .h y .m donde use los tipos swift o puede importarlo en el .pch.
Entonces, si mi módulo (proyecto) se llama "Proyecto de prueba", lo importaría así, en el archivo .pch de mi proyecto (justo allí):
#import "Test_Project-Swift.h"