Desarrollo multiplataforma con .NET ( Xamarin )

Objetivo

Conocer lo interesante del mercado de aplicaciones móviles, repasar los pros y contras de algunas tecnologías muy conocidas para el desarrollo de aplicaciones multiplataforma móvil, y conocer la alternativa perfecta para desarrolladores .NET a la creación de aplicaciones nativas para iOS, Android y Windows Phone.

Introducción

El desarrollo de aplicaciones móviles es un negocio emergente, por ello la mayoría de las ofertas de empleo para ingenieros actualmente está relacionado con ello. Esto es debido a que cada día somos más las personas conectadas entre sí a través de un teléfono móvil. Para hacernos una idea de cómo está evolucionando el mundo móvil echémosle un vistazo a la siguiente gráfica:

image

Como dato interesante tenemos que saber que la población mundial se estima en 7.000 millones de personas, y en esta gráfica podemos ver el número de dispositivos nuevos que se fabrican por año. Es sorprendente comprobar como solo este año 2014 se van a fabricar más de 1.000 millones de teléfonos. La estimación para el año 2014 es que en el mundo habrá más de 34.000 millones de smartphones acumulados, una auténtica barbaridad si recordamos la cifra de 7.000 millones de habitantes, por ello empresas como Google o Facebook tienen el foco puesto en formas de llevar la conectividad a aquellas zonas del planeta en las que aún no llega internet ni la telefonía móvil. También es interesante comprobar como este año 2014 será el primer año donde el número de tabletas fabricadas supera al número de ordenadores desktop  y laptops, estos datos ya no son desconocidos por nadie, por ello cualquier empresa a nivel mundial debe saber por pequeña que sea, que si crea una aplicación móvil y la coloca en los marketplaces podrá situarse en el bolsillo de muchos usuarios potenciales por un coste ínfimo.

Desde el punto de vista de los desarrolladores cada vez es más complicado abarcar todas las tecnologías necesarias para hacer desarrollos en la mayoría de los sistemas operativos móviles, ya que las empresas demandan a ser posible que sus aplicaciones estén en todos los móviles y desconocen las dificultades técnicas que esto implica.

Algunas de las plataformas móviles más conocidas actualmente son:

  • Android
  • iOS
  • Windows Phone
  • Symbian
  • RIM
  • FirefoxOS
  • UbuntuOS

Cada vez más empresas intentan sumarse al carro ya que saben que será el futuro estar ahí. Además de estos sistemas operativos con tecnologías diferentes luego existen muchos marketplaces diferentes, por ejemplo Nokia acaba de estrenar su NokiaX con un nuevo marketplaces para aplicaciones Android, o Amazon tiene su KindleFire con otro marketplace diferente.

Todo esto hace prácticamente imposible que pequeñas empresas de desarrollo de software puedan crear aplicaciones móviles para todos los móviles, ya que es necesario tener diferentes equipos especializados en diferentes tecnologías y lenguajes de programación, pero la demanda sigue estando ahí. Además muchas empresas grandes que quieren crear su primera aplicación no entienden que el coste de desarrollar su app móvil para que funcione en cualquier teléfono tenga un coste muy elevado, ajenos a todos los aspectos tecnológicos.

Como he dicho antes, la demanda es tan grande que hace necesario no solo que las grandes desarrolladoras de software puedan crear estas aplicaciones, sino que incluso desarrolladores freelance puedan hacerlo, por ello han aparecido una serie de tecnologías para permitir desarrollar aplicaciones “multiplataforma”, por ejemplo:

 

image image image image

Existen muchas más, pero estas son algunas de las más conocidas. Estas tecnologías se basan en crear aplicaciones nativas del dispositivo y colocar a pantalla completa un navegador web (similar a si el usuario entrara en el navegador de su teléfono y visitara una web), de esta forma se intenta simplificar y en vez de desarrollar una aplicación móvil, pues desarrollar una web que se vea bien en todos los navegadores móviles. Intenta aprovechar el hecho de que actualmente existen muchos más desarrolladores web que desarrolladores móviles que pueden ser fácilmente reconvertidos a desarrolladores de aplicaciones usando alguna de estas tecnologías.

Hasta aquí todo parece muy bonito, pero poco a poco van apareciendo más inconvenientes con estas tecnologías, algunas de ellas son:

  • El rendimiento es bastante malo incluso en dispositivos modernos, ya que se suelen utilizar lenguajes interpretados como javascript y dependen de las implementaciones del los navegadores en cada sistema operativo.
  • PhoneGap como el más conocido en este punto, es un proyecto cedido a la comunidad por lo que le cuesta estar actualizado.
  • El bajo rendimiento hace imposible crear aplicaciones con animaciones o transiciones fluidas, por lo que comparado con aplicaciones nativas a nivel de vistosidad de interfaz hay muchas limitaciones.
  • En Android por ejemplo, existen más de 14 versiones del SO en la calle, esto conlleva a que hay más de 14 versiones del navegador, y por lo tanto cada vez es más difícil garantizar que una web se ve exactamente igual en todos los Android del mercado, limitando el número de librarías JS o etiquetas que puedes utilizar.
  • A nivel de interfaz todo queda resuelto con el motor de dibujado del navegador, pero a nivel de lógica de la aplicación, debes hacer uso de Plugins escritos en los lenguajes nativos de la plataforma, para los cuales suele cumplirse la ley de Murphy (están todos menos el que buscas, están todos actualizados menos el que buscas, etc) y por tanto toca escribirte un plugin en el lenguaje nativo.
  • No se utilizan los controles nativos de cada plataforma.
  • Las aplicaciones no suelen diseñarse para verse en un dispositivo concreto, a una resolución concreta con un aspect ratio concreto, por lo que el resultado son controles estirados o desaprovechamiento del espacio.

Bueno aquí alguno de los inconvenientes, los cuales muchos son subjetivos (para gustos 32bits de color como diría un amigo mío) y muchos defensores acérrimos de estas tecnologías podrán argumentar que el rendimiento no es tan malo, o que a nivel de interfaz de usuario se puede hacer cualquier cosa igual al nativo.

Según mi experiencia personal, la conclusión es: (Spoiler Alert)

Crear una única aplicación que funcione bien en todas las plataformas móviles –> !!Es un mito!!

¿Por qué?

Pues por el Look & Feel, los usuarios esperan que las aplicaciones de su dispositivo móvil se comporten todas similares. Si en las aplicaciones hay un botón pues que este botón no solo se parezca al del resto de las apps de mi teléfono si no que también se comporte igual (solo posible si se utilizan los controles nativos de cada plataforma), el usuario espera que si su teléfono tiene un botón hardware para hacer back pues que la app no lo tenga, tienen ya interiorizada la navegación. Por ejemplo, los usuarios de Windows Phone esperan un control pivot o panorama en sus aplicaciones, esperan una estética, comportamiento y transiciones similares a las del sistema operativo, una organización de la arquitectura de la información en sus aplicaciones muy concreta al estilo Windows Phone, sino pues está el caso extremo de que los usuarios sean incapaces de manejar la aplicación y terminen borrándola. Si los dispositivos a nivel hardware son tan similares, es más hay modelos en Samsung por ejemplo con Android y Windows Phone, ¿qué diferencia tener un dispositivo de otro? pues el sistema operativo y las apps, los usuarios que se compran el último modelo con su sistema operativo favorito quieren que las apps aprovechen su teléfono y sentir que estas han sido desarrolladas para él.

image

Y ¿esto es así porque sí? ¿hay alguien que haya hecho un estudio sobre ello? Pues concretamente tenemos el caso de Facebook, empresa mundialmente conocida la cual desarrolló su aplicación móvil usando HTML. Para esta tarea seguramente puso a grandes profesionales y el resultado podemos analizarlo de muchas formas, pero una de ellas fue (para mi la importante), si a los usuarios de Facebook les gustó o no dicha app en sus móviles. Una forma de ver esto es observar sus reviews en el store:

image

La mayoría de los usuarios puntuaron esta aplicación con una sola estrella. Tras esto Facebook hizo la prueba de re implementar sus aplicaciones de forma nativa y ¿cuál ha sido la opinión de los usuarios en este caso?

image 

Pues que la mayoría de estos ahora han valorado esta aplicación con 5 estrellas, esto posiblemente demuestra que los usuarios esperan grandes experiencias de sus aplicaciones, que estas aprovechen el teléfono de última generación que tienen y les molesta mucho comprarse un teléfono nuevo y que una aplicación vaya lenta, no se parezca al resto de apps que tienen, o no sepan usarla porque tiene una navegación más al estilo de otro sistema operativo móvil.

Si estamos de acuerdo con todo esto, lo que nos queda es desarrollar nuestras apps de forma nativa. Llegados a este punto es cuando nos interesará la tecnología de Xamarin, la cual asumiendo que el desarrollo nativo es lo que los usuarios quieren nos ayuda a reducir tiempos de desarrollo y costes. Xamarin es el nombre de una empresa joven y a muchos les asusta esto de confiar en una empresa joven, por lo que repasaremos un poco la trayectoria del equipo de Xamarin.

Todo empezó en octubre de 1999 cuando Miguel de Icaza y Nat Friedman fundaron la empresa Ximian y esta era una proveedora de software libre para Linux e Unix. En Julio de 2001 tras el lanzamiento de la plataforma .NET, Miguel de Icaza estuvo trabajando en una implementación libre (para plataformas no Microsoft) del framework de .NET y así nació el proyecto Mono, que permitía usar lenguajes como C# para crear aplicaciones en Linux. En Julio de 2003 Ximian fue absorbida por Novell, durante este periodo continuaron mejorando el proyecto Mono y sacando nuevos proyectos basados en él. Por ejemplo, ellos fueron los que desarrollaron la tecnología Moonlight que fue una implementación para plataformas no Microsoft de Silverlight. Además de esto en su periodo en Novell, empezaron a desarrollar dos tecnologías llamadas Monodroid y Monotouch, las cuales hacía posible crear aplicaciones para Android y iOS usando mono. En 2011 Novell decide prescindir del equipo de Mono (unos 25 desarrolladores) y Miguel de Icaza vuelve a ponerse en contacto con Nat Friedman para fundar esta vez Xamarin y continuar con el proyecto Mono y los desarrollos alrededor de este.

Bien, ahora que estamos situados y conocemos un poco mejor a los que están detrás de este proyecto, estudiemos qué nos proponen con sus tecnologías Xamarin.iOS y Xamarin.Android. Xamarin nos da una muy buena alternativa para el desarrollo nativo en móviles, apoyándonos sobre la tecnología .NET (a través de mono) para mejorar la productividad.

image

Su propuesta de desarrollo para las plataformas de desarrollo más importantes (Windows Phone, iOS y Android) es la siguiente: desarrollar una interfaz de usuario nativa con los controles de cada plataforma, consiguiendo de esta forma la gran experiencia nativa que estábamos buscando, y a nivel de lógica de la aplicación en vez de desarrollar cada app con lenguajes diferentes como c++, java u objectiveC, desarrollar usando C# para todas, compartiendo por tanto la lógica de negocio de las aplicaciones para las tres plataformas móviles. Gracias a la productividad del lenguaje C# y a las PCLs ahora compatibles con Xamarin (Portable Class Library), esto hace que podamos compilar una librería solo una vez con unos mismos parámetros y dicha librería pueda ser enlazada desde la aplicación de Windows Phone, iOS e Android.

 

Xamarin.iOS

Empecemos analizando Xamarin.IOS:

  • ¿Qué es?
    • C# en iOS (iPhone, iPad)
  • ¿Qué no es?
    • Silverlight en iOS
    • Compact Framework para iOS
    • Desarrollo de apps en iOS sin necesitar un Mac (aunque existe la posibilidad de máquinas virtuales locales o en cloud como las que ofrece http://www.macincloud.com/)

¿Cómo sería el espacio de trabajo de un desarrollador que utilice Xamarin.iOS? Como dicen que una imagen vale más que mil palabras, aquí dejo un ejemplo práctico mío en casa:

image

Desarrollando en C# desde Visual Studio una aplicación para iOS, puedes compilar en Windows pero no puedes ejecutar, para ello necesitas tener emparejado un Mac por wifi por ejemplo a través de una app que viene con Xamarin. De esa forma cuando le das a desplegar “play” en Visual Studio, el código es enviado al Mac y este tras compilar a nativo es capaz de desplegar en un dispositivo con iOS. Lo interesante de todo esto es que puedes depurar,  y si pones un breakpoint en Visual Studio cuando tu app llega a esa línea en el dispositivo físico, el Visual Studio se para y puedes leer el valor de todas las variables independientemente de todo lo que está pasando por debajo. Con ello consigues desarrollar con apps desde Visual Studio aprovechando todas las herramientas de este gran IDE de desarrollo.

Otra opción es desarrollar directamente desde MacOS utilizando Xamarin.Studio, una versión del proyecto Monodevelop específica para desarrollar con Xamarin. También puedes desplegar sobre el emulador que viene con el SDK de Apple junto al Xcode:

 image

Algo muy interesante de las versiones actuales de Xamarin.iOS que no estaba en las versiones iniciales es que para crear la interfaz de usuario nativa (ficheros xib), podemos usar directamente XCode o un nuevo editor visual en Xamarin Studio:

image designer_new

 

¿Pero cómo es posible que una aplicación en C# usando mono corra en iOS, si Apple eliminó hace años la posibilidad de que las aplicaciones en su plataforma pudieran modificar su código en tiempo real? Algo que afectó a las aplicaciones que se desarrollaban con flash por ejemplo, y algo necesario para que el CLR de mono vaya Jiteando código en tiempo real.

Pues la solución que dio el equipo de Xamarin fue usar AOT (Ahead Of Time o precompilación a binario), apoyándose en que el hardware de los dispositivos iOS es bastante similar. Sino esto implicaría pues que dependiendo de la arquitectura hardware la aplicación final precompilada funcionaría o no. Esto no es nuevo, Microsoft tiene desde hace tiempo una herramienta llamada NGen, el problema es que al ser compilado a binario al igual que cuando compilas una aplicación en C++ para desktop pues necesitas una versión para x86 y otra para x64. Por suerte esto no ocurre en iOS ahora mismo, y si ocurriera la solución sería similar a la que está planteando Microsoft ahora con .NET native para aplicaciones en su store, la idea es compilarlas a binario de la máquina para conseguir un rendimiento prácticamente igual al desarrollo en C++ (ya que se utiliza directamente el compilador de C++ con todas sus optimizaciones) para cada arquitectura y subir todo esto al store. Cuando un usuario vaya a descargar una app este enviará al servicio su arquitectura y por tanto se descargará el binario para su arquitectura exacta, siendo por tanto transparente para el usuario.

 

Xamarin.Android

Analicemos ahora Xamarin.Android, qué es lo que nos ofrece:

  • No necesitamos un Mac
  • Completo soporte desde Visual Studio
  • Xamarin Studio como IDE de desarrollo gratis en Windows y Mac
  • Compilación embebiendo un runtime de mono en la aplicación (JIT)

A nivel de arquitectura sobre todo para temas avanzados es necesario conocer que internamente tenemos:

image

El sistema operativo Android, nuestra aplicación corriendo sobre el mono runtime embebido ejecutando nuestro código y como para ciertos bindings (acceso a controles o servicios del SO) internamente hay comunicación contra las APIs en java pues Dalvik está corriendo, esto solo hay que tenerlo en cuenta para ciertos temas avanzados. Por ejemplo en un caso muy concreto en el que estábamos trabajando, estábamos implementando un binding nativo para el acelerómetro y los valores vienen dados por una API en java, y (X,Y,Z) venían en forma de array. Al copiar estos valores era necesario disposear manualmente el array de java si no queríamos tener un memory leak. Por suerte ya existen múltiples bindings hechos para evitar que usuarios de Xamarin.Android tengan que preocuparse de estas cosas, y puedan centrarse en el desarrollo de sus apps.

La integración en Visual Studio de Xamarin.Android es mejor, la compilación es más rápida al no requerir enviar nada a otro pc, la depuración también es buena en las últimas versiones de Xamarin.Android e incluso tenemos un diseñador de interfaz para generar los ficheros nativos “axml” desde Visual Studio:

image

Para probar nuestras apps podemos enchufar directamente nuestro dispositivo Android a nuestro PC con Windows y desplegar desde Visual Studio directamente de forma bastante cómoda, si queréis probar en un emulador, os recomiendo que no uséis el oficial de Google, su rendimiento es vergonzoso (lo iba a poner más suave pero es que se lo merece y con mayúsculas). Mucho mejor usar los emuladores de Genymotion que corren sobre x86 y VirtualBox, y dan un gran rendimiento. El problema es que no podéis tener HyperV activado en vuestras máquinas, por lo que habrá que elegir.

Resumen de la forma de desarrollo:

  • Crea la interfaz de usuario nativa de tus aplicaciones, para conseguir la experiencia que los usuarios quieren, para ello xaml en Windows Phone, axml en Android y xib en iOS, lo puedes hacer con los editores nativos o con los propuestos aquí.
  • Comparte todo el código de lógica de tus apps usando C# + PCL, de esta forma puedes tener servicios en Azure por ejemplo, que utilicen exactamente el mismo código en Android, iOS, Windows, si hay cambios del servicio o errores, los corriges una vez en código y se corrigen en todas las plataformas. Facilitando mucho el mantenimiento de estas.

Las tecnologías de Xamarin, son potentes y está bien actualizadas y por ello habrá que “pasar por caja” si quieres usarlas.

 

ShowCase

¿Qué aplicaciones se han hecho con esta tecnología y qué resultados se han obtenido?

Xamarin Mobile World Congress App

image

Esta aplicación fue desarrollada por el equipo de Xamarin, los resultados que presentaron fueron:

  • iPhone + iPad (2.476 LOC / 2 apps) – 57% reutilizado
  • Android (1095 LOC)- 60%
  • WP7 (896 LOC) – 65%

Rdio

image

Los desarrolladores de este servicio de música stream vía internet destacaron:

  • Que podían sacar updates al mismo tiempo, si tener que esperar por tener 3 equipos distintos unos a otros para lanzar una actualización con un cambio en el servicio de streaming.

 

iCircuit

image

Los desarrolladores de este diseñador de circuitos, destacaron tras su desarrollo con Xamarin:

  • La productividad del lenguaje C# comparado con desarrollos nativos en C++.
  • Y según ellos reutilizaron para su versión Windows Phone y iOS entre el 70% y el 80% del código.

TouchDraw

image

Los desarrolladores de este diseñador de diagramas, destacaron:

  • Algo que antes en nativo habían empleado 3 semanas ahora lo habían hecho en 1.
  • Compartir el código de lógica reducía mucho el Bug Fixing (mantenimiento).

Sage Murano, Sage Despachos y Sage Contaplus

image

Personalmente me ha tocado gestionar este proyecto en Plainconcepts, y estos son los datos de nuestra propia experiencia:

  • Teníamos que desarrollar 12 aplicaciones nativas, (3 aplicaciones para las versiones Phone y Tablet en Android e iOS)
  • Nos hemos aprovechado del uso de Universal Apps para tener una misma solución en Phone y Tablet con diferentes ficheros de layout e interfaz.
  • El proyecto lo hemos desarrollando usando Visual Studio 2013 y gestionado como un proyecto de Git a través de TFS 2013 (Xamarin Studio tiene integración con Git por lo que es más fácil compartir código entre Mac y Windows).
  • Utilizando los emuladores de iOS nativos o del SDK y los de Genymotion para Android que también se integran directamente con Visual Studio.
  • Utilizando MVVMCross para la navegación por ViewModels.
  • Hemos reutilizado entre el 50% y el 60% del nuestra base de código entre las 12 apps.
  • 12 apps nativas desarrolladas por 3 desarrolladores en 3 meses y medio.

 

Este es el aspecto del proyecto en Visual Studio, para Android e iOS:

image image

 

Extra

Para terminar algunas cosas también muy interesantes alrededor de este proyecto, son:

La existencia de un marketplace de controles cross-platform (Xamarin components), algunos gratis y otros de pago, interesante tanto para desarrolladores de apps como para empresas que se dediquen a la creación de controles para terceros:

image

Ahí existen algunos controles o librerías interesante como Xamarin.Mobile, que nos ofrece una API unificada (Windows Phone, iOS, Android) para acceder a diferentes servicios muy comunes de las plataformas, directamente desde nuestro código C#:

image

y por último el servicio de testCloud de Xamarin, el cual aún no está abierto para todo el mundo y para poder usarlo hay que hacerlo previo contacto con ellos. Ofrece una forma fácil de evitar a los desarrolladores tener que comprar múltiples dispositivos Android para probar sus aplicaciones en ellos, (este problema de fragmentación en Android supone un coste muy elevado de compra de dispositivos para muchas empresas). Pues bien este servicio ofrece la posibilidad de realizar pruebas sobre emuladores o dispositivos físicos que son grabados por cámaras y comprobar si nuestra app funciona bien en la mayoría de estos dispositivos:

image

Algo muy interesante además es que cada dispositivo muestra la información de porcentaje a nivel mundial de ese tipo de dispositivo que existe, de manera que si tu aplicación funciona en la mayoría de los dispositivos Android menos en uno y este tiene un porcentaje muy pequeño, por ejemplo el 1% a nivel mundial, pues ya puedes tener argumentos tú o tu cliente para decidir si es asumible que en dichos dispositivos la aplicación no se vea perfectamente.

 

Bueno pues nada más, espero que todo esto aclare qué es y qué no es Xamarin, y esto os ayude a decidir cuándo me interesa usar Xamarin y cuándo no, lo cual depende de muchísimos aspectos, como capacidades del equipo, costes, tiempos, etc.