El poder de C y Swift juntos

Se llama Dark Jedi a un Jedi que practica el Lado Oscuro, pero sin ser un Señor del Sith. Alguien que domina ambos lados de la Fuerza, sin estar restringido por ninguno de ellos.

Lo cierto es que no es mala idea, y a menudo es conveniente tirar de librerías en C++ (¡lagarto, lagarto!), C y por supuesto Objective C.

Usar C (y Objective C) desde Swift es particularmente facil.

Frameworks programadas en Objective C

El caso de frameworks que han sido creadas con Objective C y compiladas como módulos del LLVM, es trivial:

 

Todos hemos usado esto en cualquier proyecto de Swift:

Esto funciona porque al hacer un Import Foundation el compilador va a leer un fichero binario (el módulo) que contiene toda la información necesaria para poder llamar a ese código.

Ahora bien, ¿qué pasa cuando ese código “forastero” no está empaquetado en un módulo?

Usar librerías C o clases Objective C desde Swift

Supongamos que tienes una clase en Objective C en un proyecto Swift. ¿Cómo la usas?

Por otro lado, supongamos que tienes una librería C, y necesitas usarla desde Swift: ¿cómo le das la información necesaria sobre las funciones y tipos dentro de ella?

La solución, en ambos casos pasa por darle esa información al compilador de Swift en forma de un fichero de cabecera de C.

A este fichero de cabecera, se le llama Bridging Header, o fichero puente.

Bridging Header

Este fichero a veces te lo crea Xcode automágicamente, pero vamos a ver como hacerlo manualmente y así entender cómo funciona.

Como ejemplo, vamos a usar la función dispatch_benchmark() de Grand Central Dispatch, que hemos visto en otro artículo. Como recordarás, dicho función existe en la librería, pero no está exportada.

Por o tanto, para usarla en C u Objective C, teníamos que que declararla:

¿Cómo la podemos usar en Swift?

Declarándola…en el bridging header.

 

Crear un Bridging Header

  1. Crea un nuevo fichero de tipo C Header en tu proyecto. Puedes llamarlo como quieras, aunque el estándar es <NombreDeTuProyecto>-Bridging-Header.h
  2. Declara la función de marras (¡no te olvides de importar Foundation!).
  3. Ahora viene algo muy importante. El compilador no sabe quién es el fichero bridging header. No lo detecta por el nombre, hay que especificarlo. Vete a las propiedades del proyecto. Una vez ahí, vete a Build Settings y busca Objective-C Bridging Header.
  4. Escribe el nombre de fichero. Si no está en la misma carpeta que el proyecto, tendrás que indicar la ruta.
  5. Compila, y ¡listo!

Con esto ya podrías usar dispatch_bridge() desde Swift.

 

Bridging Header y Frameworks Swift

En una framework hecha en Swift, no puedes usar un Bridging Header. ¿Y si tienes que usar código C u Objective C?

Hay solución, pero tendríamos que saber más sobre módulos, así que lo veremos en otro artículo.

Si tienes algo que deseas compartir o quieres formar parte de JustCodeIt, escríbenos a [email protected].



Share this:

2 comments, add yours.

Uriel

Buenas Fernando! Gran artículo, pero he visto que hay una pequeña errata en el apartado de crear el bridging-header. Cuando mencionas el paso 1, al decir la convención que existe para nombrarlo, pusiste “.c” en lugar de “.h”. Para cualquier persona con conocimientos no será ningún problema pero a gente amateur entiendo que podría confundirles. Un saludo.

Leave a comment