Reduciendo tiempos de compilación en proyectos iOS

Una de las primeras cosas que recomiendo e intento hacer cuando empezamos un desarrollo es configurar las builds de integración y despliegue continuos desde el minuto 0. Hay que tener en cuenta que tiempo que tarda en ejecutarse una build es, cómo decirlo, oro.

Y es que tras configurar una github action para un proyecto de iOS me sorprendió la cantidad de tiempo que tardaba en ejecutarse… Casi 30 minutos. Así que tocaba “arremangarse” y buscar cómo optimizarlo.

Da igual si lo haces con githubactions, Jenkins, Teamcity, Azure Devops, etcc … Hay que hacer dos cosas:

Cachear el contenido de “derivedData”

Busca la forma de cachear ese directorio, de lo contrario, en cada build que se ejecute se descargará y compilará todas las referencias que tengas en tu proyecto.

Aquí os pongo cómo puedes hacerlo si usas githubactions:

- uses: actions/cache@v2.1.7
  name: "Cache: Expensive Dependencies "        
  with:
    path: |
      ./DerivedData/Build
      ./DerivedData/SourcePackages            
    key: ${{ runner.os }}-expensive-dependencies-${{ hashFiles('**/Podfile.lock','**/Package.resolved') }}
    restore-keys: |
       ${{ runner.os }}-expensive-dependencies-

Estamos cacheando ese directorio, que en mi caso está en la raíz del proyecto porque cuando ejecuto el comando xcodebuild, le indico que use ese directorio como derivedDataPath. Esto se consigue añadiendo al comando xcodebuild el parámetro “-derivedDataPath ./DerivedData”, o el directorio que quieras. Si no se lo indicas, el directorio derived data se encuentra en /Library/Developer/Xcode/DerivedData/”miproyecto”

Os recomiendo que sólo cacheéis los directorios de Build y SourcePackages, ya que son los que contienen el código y el resultado de las compilaciones de las dependencias. El resto es para cache de símbolos logs, resultados de tests.. que si los incluís en la cache se va a estar invalidando en cada build y la volverá a guardar… y eso aunque no es mucho, es tiempo… y el tiempo es…

Prestad especial atención también a cómo se generan las claves para la cache, estamos aprovechando el hash del archio podfile.lock para generar una nueva entrada en la cache cuando se añada un nuevo paquete.

Añadir un parámetro a xcodebuild.

El segundo punto importante y que no se nos debe olvidar es pasarle al comando xcodebuild el parámetro:

-IgnoreFileSystemDeviceInodeChanges=YES”

Con este parámetro le estamos diciendo a xcode que desactive una opción interna que hace que el Swift Package Manager invalide lo que haya en DerivedData porque se está ejecutando en una máquina diferente… o algo así he entendido de esto https://stackoverflow.com/questions/53753511/is-it-possible-to-copy-an-xcode-derived-data-cache/54055857#54055857 

También está la otra opción que se describe en el post de stackoverflow:

defaults write com.apple.dt.XCBuild IgnoreFileSystemDeviceInodeChanges -bool YES

Pero esto último no lo he probado. Así que si queréis probarlo genial, así no hay que pasarlo al comando xCodebuild.

 

Espero que os sirva.

Azure Devops, Xcode y el error IPA processing failed

Seguramente por mi “L” de desarrollador iOS he estado un día entero investigando porqué después de añadir los paquetes de Firebase Crashlytics y FirebaseAnalytics, la pipeline que genera el IPA empezó a fallar. Compilaba el paquete, hacia el Archive, pero cuando hacía el export, termina dando el error Error Domain=IDEFoundationErrorDomain Code=1 “IPA processing failed” UserInfo={NSLocalizedDescription=IPA processing failed}

Despues de un día intentando reproducirlo en local y viendo que todo funcionaba perfectamente me dí cuenta que la versión del sdk iphoneos que tiene instalada la máquina de azure era la 14.4. y yo en local lo tengo todo a la última….

Jugando a detective colombo, pensé “¿y si no le gusta que halla añadido la referencia a traves del package manager?” … pues por probar y ya que no se me ocurría nada más, instalé las dependencias como paquetes POD … y ALELUYA!!!

Por fin me genera el ipa como $Deity manda

 

Espero que le sirva a alguien que como yo aún va con la L

 

Aprendiendo Swift TDDando

Bueno, ¡cuánto ha llovido desde el último post!

Sólo quería dejar aquí presente algo que he estado haciendo y es aprender ha desarrollar aplicaciones nativas en iOS con Swift. Y para eso aquí tenéis un repo donde voy metiendo cositas de vez en cuando: https://github.com/juanlao/BenfordsLaw

El objetivo de este repositorio es aprender plataformas nuevas e ir descubriendo los intríngulis de cada una de ellas con TDD (Test Drive Development) que tengo la sensación de que no va a ser un mal camino para aprender  los entresijos de un nuevo lenguaje/plataforma. Y además seguro que aprendo cosas nuevas sobre cómo hacer tests unitarios 🙂

Espero que os sirva

 

TFS, Xamarin y MSTests

Hace un tiempo vimos un pequeño truco para poder ejecutar tests en las builds de TFS para proyectos Windows Phone.

Me ha sido necesario hacer lo mismo con proyectos con Xamarin Android y Xamarin iOS y aquí os pongo mi experiencia y cómo lo he resuelto. Continue reading “TFS, Xamarin y MSTests”

[Evento CartujaDotNet] Wave Engine

Wave EngineImagina que quieres hacer un juego, pero sólo quieres programarlo una vez y desplegarlo en la mayoría de plataformas posibles.

Deja de soñar y aprende a usar Wave Engine y podrás desplegar tus juegos en iOS, Android, Windows 8 y Windows Phone.

Los grandes Marcos Ligthyear y David Woody nos enseñarán todo lo necesario (y quizás algo más … ) para empezar a sacarle partido a Wave.

¿Dónde y cuando?

En el Cloud Pointing de Sevilla.

c Biología, 12, Edificio Vilamar 2, 3ª Planta
Parque Empresarial Nuevo Torneo
41015 Sevilla

El Jueves 23 de Mayo de 19:30 a 21:30.

Aquí tenéis juegos reales hechos con Wave Engine. Y estas son  unas cuantas demos tecnológicas.

¿Te lo vas a perder? Pues regístrate aquí

Difoosion

Me llena de orgullo y satisfacción que me hayan acogido en Difoosion como editor en su blog sobre noticias de Windows Phone: Winphone metro.

Logo de Winphone Metro

Tienen una red de blogs bastante interesante sobre el mundo móvil, no sólo de Windows Phone:

Logo Andro4all

Andro4All: Noticias sobre la plataforma Android.

Logo Applesencia

Applesencia: Noticias sobre Apple.

Logo Xombit

Xombit: Noticias sobre ciencia, tecnología, cultura, gadgets, series y juegos.

Logo XombitGamesXombit Games: Noticias sobre videojuegos de todas las plataformas

Uyuyuy, una sorpresa de última hora y es que ayer se lanzó:

Logo SportAdictosUn blog sobre deporte, salud y nutrición.

La verdad es que es una red de blogs muy recomendable para estar al tanto de lo que se cuece sobre estos temas y es que se actualizan bastante a menudo y creo que a los que me leéis os puede interesar.

Espero que os gusten.

Más tiempo para Cell·APP Awards

Las plegarias han sido oídas y  hemos ampliado el plazo para presentar juegos y aplicaciones a Cell·APP Awards:

Cell·App Awards

Desarrolla tu app usando CELL·SDK. Debes rellenar este formulario para participar y enviarnos el formulario de suscripción.

  • Fin de Inscripción: 31/05/2012
  • Último día para enviarnos tu app: 15/06/2012
  • Periodo de votaciones Online: Empezará una vez envíes tu app y nosotros la subamos. Este periodo acabará el 26 de Junio
  • El Jurado valorará las apps más votadas a partir del 28 de Junio.
  • La entrega de premios será el 29 de Junio.

Todavía no tienes Cell·SDK?! O_o

Pues descárgalo aquí.

Cell·SDK y el emulador de Android

Hace unas semanas se publicó una actualización del emulador de Android que muchos estábamos esperando.

Entre otras cosas, la característica fundamental, y una de las más esperadas, es que esta versión del emulador por fin soporta la aceleración de GPU, necesaria para ejecutar aplicaciones que necesitan OPEN GL 2.0. Continue reading “Cell·SDK y el emulador de Android”

Push Notifications en Cell·SDK

La semana pasada publicamos Cell·SDK 1.2 con un montón de nuevas características y algunas correcciones que hacen del desarrollo multiplataforma en iOS, Android y Windows Phone aún más sencillo.

En el post de hoy vamos a ver cómo enlazar lo que tenemos en el tutorial de Push notifications para Windows Phone y lo que podemos encontrar en la web de Microsoft sobre cómo mandar notificaciones a nuestros dispositivos.

Con el mismo código fuente que tenemos disponible en Github para la aplicación de ejemplo en el  dispositivo nos va a valer para este ejemplo.

Tenemos que tener en cuenta que debemos programarnos una pequeña aplicación/servicio para poder enviar notificaciones al servicio de notificaciones de Microsoft. Tal y como vemos en el diagrama y documentación de Microsoft:

Arquitectura Push

Nosotros tenemos que implementarnos el “Cloud Service” así que vamos a ver un ejemplo de cómo hacerlo según se indica aquí. De este último enlace sólo nos interesa la parte de “Sending a Toast Notification

Vamos a crear un proyecto de ASP.NET vacío y vamos a incluir cuatro controles TextBox y un botón para enviar la notifiación:

Página de envío

Ahora vamos a darle código al evento clic del botón:

protected void SendToast_Click(object sender, EventArgs e)
 {
 try
 {
 // Get the URI that the Microsoft Push Notification Service returns to the push client when creating a notification channel.
 // Normally, a web service would listen for URIs coming from the web client and maintain a list of URIs to send
 // notifications out to.
 string subscriptionUri = TextBoxUri.Text.ToString();

HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);

// Create an HTTPWebRequest that posts the toast notification to the Microsoft Push Notification Service.
 // HTTP POST is the only method allowed to send the notification.
 sendNotificationRequest.Method = "POST";

// The optional custom header X-MessageID uniquely identifies a notification message.
 // If it is present, the same value is returned in the notification response. It must be a string that contains a UUID.
 // sendNotificationRequest.Headers.Add("X-MessageID", "");

// Create the toast message.
 string toastMessage = "<?xml version="1.0" encoding="utf-8"?>" +
 "" +
 "" +
 "" + TextBoxTitle.Text.ToString() + "" +
 "" + TextBoxSubTitle.Text.ToString() + "" +

" " +
 "";

// Set the notification payload to send.
 byte[] notificationMessage = Encoding.Default.GetBytes(toastMessage);

// Set the web request content length.
 sendNotificationRequest.ContentLength = notificationMessage.Length;
 sendNotificationRequest.ContentType = "text/xml";
 sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast");
 sendNotificationRequest.Headers.Add("X-NotificationClass", "2");

using (Stream requestStream = sendNotificationRequest.GetRequestStream())
 {
 requestStream.Write(notificationMessage, 0, notificationMessage.Length);
 }

// Send the notification and get the response.
 HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
 string notificationStatus = response.Headers["X-NotificationStatus"];
 string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
 string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];

// Display the response from the Microsoft Push Notification Service.
 // Normally, error handling code would be here. In the real world, because data connections are not always available,
 // notifications may need to be throttled back if the device cannot be reached.
 TextBoxResponse.Text = notificationStatus + " | " + deviceConnectionStatus + " | " + notificationChannelStatus;
 }
 catch (Exception ex)
 {
 TextBoxResponse.Text = "Exception caught sending update: " + ex.ToString();
 }

Este código puede estar tanto en una aplicación web, una aplicación de Windows forms, un servicio de Azure, etc…

Tan sólo tenéis que montarlo, desplegar la aplicación de ejemplo de github en el dispositivo ó en el emulador y copiar el Channel ID que saldrá en la ventana de Output de Visual Studio:

Channell ID en Visual Studio

Este código lo introducimos en la página web que hemos creado en el textbox primero y recibiremos en el dispositivo o emulador una notifiación Toast:

Toast Notification

Hay tres tipos de notificaciones para Windows Phone que podemos enviar:

  • Toast: Con documentación y ejemplos aquí
  • Tile: Con documentación y ejemplos aquí.
  • Raw: Con documentación y ejemplos aquí.

Os recomiendo que probéis a enviar otro tipo de notificaciones, en este ejemplo hemos usado el ejemplo de envío de notificaciones Toast.

Para ver el código fuente de la aplicación y cómo es la API Unificada para Android, iOS y Windows Phone de Cell·SDK no tenéis más que pasaros por aquí

Espero que os sirva.

Juan María Laó Ramos.

Create your website with WordPress.com
Get started