Cargar frameworks de terceros en tus apps Xojo para iOS

El siguiente artículo ha sido publicado originalmenteen inglés en el Blog de Xojo, y en este se nos muestra como podemos cargar los frameworks de terceros en nuestras apps iOS creadas con Xojo. ¡En definitiva, más prestaciones y capacidades a disposición de nuestros productos! Y ya sabes, siempre de forma nativa, con código compilado. Por tanto, a partir de esta línea, toda la autoría pertenece a Greg O’Lone (ingeniero de Xojo) y también de Xojo.

¿Sabías que es posible cargar frameworks de terceros en tus proyectos iOS creados con Xojo? Hay realmente una buena cantidad de proyectos ahí afuera, muchos de los cuales están disponibles de forma pública en sitios como GitHub, listos para que puedas incorporarlos en tus proyectos. Si estás familiarizado con los Declare en iOS, entonces ya sabrás que la carga de un framework de tercero precisa sólo de un par de líneas adicionales de código y un paso de CopyFileStep en los ajustes de compilación.

El año pasado en la XDC 2018, Jeremie Leroy nos habló sobre el hecho de asegurarnos de que las capturas de pantaalla imitasen el método empleado por Apple, de modo que la fecha siempre fuese el 9 de Junio, la hora marcase siempre las 9:41 AM, la batería se muestre siempre llena y la señal de recepción WiFi siempre estuviese al máximo. Esto me hizo pensar en que podría sere conveniente hacer que el simulador siempre mostrase dichos valores cuando se ejecuta un proyecto iOS en modo de depuración, de modo que pudieses realizar capturas de pantalla y películas de tu app. Un modo de hacerlo es compilar y ejecutar un proyecto como SimulatorStatusMagic en el Simulador antes de ejecutar tu proyecto, pero sería mucho más útil si este proceso fuese automático. was automatic.

Crear el Framework

En primer lugar, dirígete a SimulatorStatusMagic en la página de GitHub y clona o descarga el proyecto. Tal y como ocurre con el desarrollo para iOS en Xojo, necesitarás tener instalado Xcode para este paso. Una vez hayas descargado el proyecto, haz doble clic en el archivo SimulatorStatusMagic.xcodeproj para abrirlo en Xcode. Cuando se haya abierto el proyecto, cambia el target a SimulatorStatuMagiciOS y compílalo pulsando CMD-B o bien pulsando el botón Play. Una vez se haya completado la compilación, dirígete al navegador de proyecto y selecciona el archivo SimulaotrStatusMagiciOS.framework. Usa el clic derecho y selecciona la opción Mostrar en el Finder.

Crear el Proyecto

Comencemos asegurándonos de que el framework estará disponible para tu proyecto en tiempo de ejecución.

  1. Crea una carpeta en tu disco con el nombre SimulatorStatusMagic y copia en ella el archivo de framework que acabas de crear.
  2. Ejecuta Xojo y crea un nuevo proyecto iOS. Guarda también el proyecto en esta carpeta.
  3. Para asegurarte de que el framework estará disponible para tu proyecto cuando lo depures, dirígete al desploegue iOS (iOS Target) en el navegador Xojo, haz clic derecho y selecciona Build Step > Copy Files. Asegúrate de que el paso recién añadido esté entre los pasos Build y Sign.
  4. Arrastra el archivo SimulatorStatusmagiciOS.framework desde el Finder a Copy Files Step.
  5. En el Inspector Xojo, escoge Applies to para que se corresponda con Debug, y Destination a App Parent Folder.

Ahora, ¡hagamos que puedas acceder al framework! Añadiremos este código en el evento App.Open de modo que la barra de estado se configure antes que cualquier otra cosa.

Lograr que el framework se cargue es realmente sencillo:

#If DebugBuild
  Declare Function dlopen Lib "/usr/lib/libSystem.dylib" (name As CString, flags As Int32) As Ptr
  Call dlopen("@executable_path/SimulatorStatusMagiciOS.framework/SimulatorStatusMagiciOS", 1 Or 8)
EndIf

La cadena mágica “@executable_path” se traduce en tiempo de ejecución en “la ubicación en la que se encuentre la aplicación”. Esto se limita a cargar el framework. Aun necesitamos acceder a los métodos y propiedades. Aviso: si estás trabajando con un framwork que se “activa a sí mismo”, como por ejemplo el que se incluye con Reveal (una excelente herramienta para localizar problemas de diseño en los layout de iOS), entonces esto es todo lo que tendrías que hacer.

Para averiguar cuál ha de ser nuestro próximo paso, necesitamos consultar la documentación y los archivos de cabecera incluidos con SimulatorStatusMagic. Vuelve a Xcode y mira en el navegador. Lo que estamos buscando es un archivo de cabecera (con una extensión .h) en el que se encuentran las definiciones de los métodos y propiedades disponibles en este framework. El único archivo que se corresponde con este criterio (y el único al que parecen apuntar los demás) se llama SDStatusBarManager.h. Este incluye parte de la funcionalidad, pero el framework está configurado para utilizar por omisión los ajustes recomendados por Apple, de modo que todo lo que haremos aquí es llamar al método enableOverrides para activarlo.

Vuevlve a Xojo y actualiza el evento App.Open:

#If DebugBuild
Declare Function dlopen Lib "/usr/lib/libSystem.dylib" (name As CString, flags As Int32) As Ptr
Call dlopen("@executable_path/SimulatorStatusMagiciOS.framework/SimulatorStatusMagiciOS", 1 Or 8)

// Empieza creando un apuntador a la clase SDStatusBarManager propiamente dicha
Declare Function NSClassFromString Lib "Foundation" (clsName As CFStringRef) As Ptr
Dim smclass As Ptr = NSClassFromString("SDStatusBarManager")

// A continuación, necesitaremos un apuntador a la instancia compartida de la clase SDStatusBarManager
Declare Function sharedInstance Lib "Foundation" Selector "sharedInstance" (clsref As Ptr) As Ptr
Dim smclassShared as Ptr = sharedInstance(smclass)

// Por último, activamos la sobreescritura
// AVISO: NO estamos utilizando intencionadamente el nombre de la librería real aquí.
// Esto es sólo para satisfacer al enlazador de Xojo. El framework correcto se utilizará en tiempo de ejecución.
Declare Sub enableOverrides Lib "Foundation" Selector "enableOverrides" (obj As Ptr)
enableOverrides(smclassShared)
EndIf

Si ejecutas ahora el proyecto, cuando este se abra ¡verás como la barra de estado cambia automáticamente a los ajustes por defecto recomendados!

Por favor, ten esto en cuenta: Estos cambios persisitirán hasta que el dispositivo del simulador que estés ejecutando se borre por completo. Si necesitas desactivarlo, puedes hacerlo usando el método disableOverrides.

Firmar Frameworks para distribución en AppStore

El último paso consiste en añadir un nuevo guión de compilación, encargado en este caso de firmar con el certificado de desarrollador aquellos frameworks que se hayan añadido al proyecto, de modo que la app pueda enviarse para su distribución en la AppStore. Para ello, añade un nuevo paso de Script de compilación al proyecto, justo después del paso Copy File añadido con anterioridad. Probablemente querrás configurar este paso en el campo Applies To: Release. El código debería de ser como este:

// sustituye el texto en la propiedad signingIdentity por el tuyo
Dim signingIdentity As String = "iPhone Distribution: Your Company (XXXXXXXXXX)"
Dim code As Integer
Dim cmd As String
Dim result As String
Dim builtApp As String

builtApp = CurrentBuildLocation + "/" + ReplaceAll(CurrentBuildAppName, " ", "\ ")

// Obtén un listado de todos los frameworks, uno por línea
cmd = "ls -d1 " + builtApp + "/*.framework"
result = Trim(DoShellCommand(cmd, 30, code))

// Si no ha ocurrido un error, firma cada uno
If code = 0 Then
Dim frameworks() As String = split(result, chr(13))
For i As Integer = 0 To UBound(frameworks)
frameworks(i) = ReplaceAll(frameworks(i), " ", "\ ")
cmd = "/usr/bin/codesign -fs """ + signingIdentity + """ " + frameworks(i)

Result = DoShellCommand(cmd, 30, code)

// Si falla el firmado, imprime el error y detén la compilación
If code <> 0 Then
print Result
cancelBuild
End If
Next i
End If
Javier Rodriguez

Consultor, desarrollador y formador con más de 25 años de experiencia. Reconocido experto en el mundo Apple, autor de varios libros sobre tecnología. Si tienes un proyecto o necesitas ayuda, ¡ponte en contacto conmigo!

Etiquetado con:

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*