Probando Embeddinator-4000: De .NET a iOS, Android o macOS nativo

Introducción

Los desarrolladores de Xamarin conocen las librerías de Bindings y la herramienta Sharpie. Hablamos de una herramienta de línea de comandos que permite automatizar la creación de una librería .NET que exponga las capacidades de la librería nativa. Sin embargo, existen una enorme cantidad de grandes librerías .NET utilizadas en Xamarin, ¿cómo podemos permitir utilizar librerías .NET desde una aplicación iOS o Android nativa?. En ocasiones arrancamos Apps Xamarin que tienen una base nativa o incluso hacemos una segunda App en Xamarin cuando ya existe una primera con código nativo. ¿No sería fantástico poder reutilizar?.

¿Qué es Embeddinator-4000?

Embeddinator-4000 es una herramienta de línea de comandos que permite convertir librerías  .NET a librerías que pueden ser consumidas por otros lenguajes.

Embeddinator-4000

La herramienta toma una librería .NET y genera los enlaces necesarios para exponer la librería .NET como una librería nativa. El gran objetivo es permitir utilizar librerías .NET en otras plataformas con código y herramientas nativas. Sigue en desarrollo y por lo tanto, se siguen añadiendo más y más funcionalidad, actualmente permite convertir de .NET a C, C++, Objective-C (plataformas Apple) y Java (Android principalmente).

La librería .NET

Si la herramienta convierte una librería .NET a una librería nativa, necesitamos una librería .NET a utilizar, ¿no?. Vamos a utilizar una sencilla librería .NET que permite consumir la API Rest Netflix Roulette (permite obtener una película recomendada aleatoria de Netflix en base a una serie de filtros como la puntuación por ejemplo).

La librería desarrollada con código C# hace peticiones HTTP a la API utilizando HttpWebRequest y deserializamos Json con DataContractJsonSerializer.

Obtener información de películas

Utilizando Embeddinator

Llega el momento de utilizar la herramienta. Pero antes de ello, repasemos los requisitos.

Para convertir a librería Objective-C:

  • macOS 10.12 (Sierra) o superior.
  • Xcode 8.3.2 o superior.
  • Mono 5.0.

Para convertir  librería Java:

  • Java 1.8 o superior.
  • Mono 5.0.
  • Xcode 8.3.2 (en MacOS) .
  • Visual Studio 2017 con SDK de Windows 10 (en Windows).

Vamos a convertir nuestra librería .NET a un .framework, librería nativa para utilizar en un proyecto nativo iOS en XCode. Comenzamos con la instalación de la herramienta. Existen dos opciones:

  • Utilizar un paquete ya preparado listo para la instalación.
  • Sincronizar el repositorio y compilar.

La instalación del paquete es sencilla y la habitual:

Instalar la herramienta

Una vez instalada la herramienta, accediendo a un terminal tendremos acceso a la herramienta de línea de comandos con objcgen.

NOTA: La ruta absoluta de la herramienta es /Library/Frameworks/Xamarin.Embeddinator-4000.framework/Commands/objcgen.

Objective-C es un lenguaje utilizado en macOS, iOS, tvOS y watchOS. La herramienta soporta todas las plataformas aunque hay diferencias en el uso.

Vamos a centrarnos en iOS. Para utilizar la herramienta contamos con una serie de parámetros:

  • Platform: Plataforma destino. Posibles valores: android, windows, macos, ios, watchos, tvos.
  • Outdir: Directorio donde vamos a obtener el resultado.

objcgen Library.dll –target=framework –platform=iOS –outdir=output -c –debug

Utilizando la herramienta

Tendremos información de cada acción realizada:

Feedback

Al concluir la herramienta,  en la carpeta de salida (en nuestro ejemplo, se ha creado una carpeta llamada output) veremos lo siguiente:

La salida

Tenemos varios ficheros interesantes, a destacar:

  • .framework: Librería nativa preparada para utilizar en desarrollo nativo.
  • binddings: Código Objective-C con nuestra librería.

Probando el resultado

Creamos un nuevo proyecto iOS desde XCode:

Nuevo proyecto

Arrastramos el .framework al proyecto:

Copiar .framework

En las propiedades del proyecto, añadimos el framework recién copiado como Embedded Binaries:

Embedded Binaries

Creamos una interfaz de usuario sencilla pero suficiente para poder probar que todo funciona como esperamos:

La interfaz de usuario

Una caja de texto donde el usuario puede introducir el nombre de una película, un botón para hacer la búsqueda y algunso textos donde mostrarle información como la descripción, la puntuación, etc.

Al pulsar el botón debemos hacer la búsqueda. En el controlador:

- (IBAction)findMovie:(id)sender {
     NetflixRoulette_NetflixRouletteFetcher * fetcher = [[NetflixRoulette_NetflixRouletteFetcher alloc] initWithMovie: _movieTxtField.text];
 
     NetflixRoulette_NetflixRouletteResult * result = [fetcher getMovie];
 
     if (result) {
          _titleLabel.text = [result showTitle];
          _yearLabel.text = [result releaseYear];
          _ratingLabel.text = [result rating];
          _descLabel.text = [result summary];
     }
}

Trabajamos con la librería .NET pero utilizando en este caso código Objective-C.

El resultado:

 

El resultado

Tenéis el código fuente del ejemplo utilizado disponible en GitHub:

Ver GitHub

Limitaciones

Mencionamos previamente que estamos ante una herramienta en desarrollo y cuenta con por supuesto algunas limitaciones:

  • No podemos utilizar dos librerías generadas con la herramienta en la misma aplicación.
  • Debido a la falta de metadatos en .NET para la gestión de nulidad, se generan NS_ASSUME_NONNULL_BEGIN.
  • Igualmente carece en estos momentos de soporte a tipos genéricos.
  • El soporte a Apple Watch está en desarrollo.
  • Etc.

Conclusiones

El pasado //BUILD fue un momento repleto de grandes anuncios. Entre ellos, uno de mis favoritos (y la herramienta estaba ya disponible en GitHub previamente) fue el anuncio y demostración de esta herramienta, Embeddinator-4000. Viene a cubrir una necesidad real que me he encontrado en más de una ocasión. Poder reutilizar código .NET en plataformas nativas al igual que ya se podía utilizar código nativo en Xamarin rompe una barrera en determinados momentos. Con mejoras en esta herramienta, Xamarin Live Player, Xamarin.Forms llegando a más plataformas (Linux incluido) o Forms Embedding el futuro a corto plazo se ve muy emocionante. Y a ti, ¿que te parece?.

Más información

Anuncios

[Tips and Tricks] Correr una App de consola .NET en la Intel Galileo

galileo-illustrationIntroducción

En la Preview Release del programa de desarrollo de Windows para IoT podemos desarrollar aplicaciones para la Intel Galileo utilizando las APIs Arduino Wiring y un subconjunto de Win32. En el pasado //BUILD 2014 en San Francisco, Microsoft anuncio la futura disponibilidad del modelo de desarrollo de aplicaciones Windows universales.

Aplicación .NET de consola

Abrimos Visual Studio y creamos una nueva aplicación de consola:

Nuevo proyecto de Consola

Nuevo proyecto de Consola

Vamos a crear una aplicación muy sencilla, nos mostrará los primeros 100 números primos. Para ello, crearemos un Helper que nos indicará si un número es o no primo:

public static bool IsPrime(int number)
{
     if ((number & 1) == 0)
          return number == 2;

     for (int i = 3; (i * i) <= number; i += 2)
     {
          if ((number % i) == 0)
               return false;
     }

     return number != 1;
}

En nuestra App crearemos un bucle con los primeros 100 números e iremos verificando si son o no primos:

Console.WriteLine("--- Primes between 0 and 100 ---");

for (int i = 0; i < 100; i++)
{
     bool prime = PrimeHelper.IsPrime(i);
     if (prime)
     {
          Console.Write("Prime: ");
          Console.WriteLine(i);
     }
}

Console.ReadLine();

Si la ejecutamos veremos un resultado como el siguiente:

100 primeros primos

100 primeros primos

Vamos a desplegar la App en la Galileo y a ejecutar la misma. Recordamos que la Galileo es una placa Open Hardware basado en el procesador Quark SoC X1000 de 32bits de Intel. Por lo tanto, si queremos ejecutar la aplicación debemos modificar la plataforma destino a x86 en las propiedades de compilación de nuestro proyecto.

Compilar en x86

Compilar en x86

Utilizamos Galileo Watcher con la Galileo conectada a nuestro equipo de desarrollo para acceder a los recursos compartidos y copiar la aplicación:

Copiamos la App en los recursos compartidos

Copiamos la App en los recursos compartidos

Todo listo!. Si ejecutamos nuestra aplicación vía Telnet el resultado es:

Ejecutando la App en la Galileo vía Telnet

Ejecutando la App en la Galileo vía Telnet

Podéis descargar el sencillo ejemplo realizado a continuación:

También podéis acceder al código fuente directamente en GitHub:

Ver GitHub

Recordar que cualquier tipo de duda o sugerencia la podéis dejar en los comentarios de la entrada.

A tener en cuenta

Hemos verificado que nuestra aplicación .NET de consola funciona perfectamente. De hecho, muchas otras aplicaciones de consola podrían funcionar. La mayoría de funciones del Core asi como mscorlib/mscoree funcionaran. Sin embargo, al comenzar a utilizar librerías dependientes no implementadas obtendremos distintos tipos de excepciones. No funciona todo lo que sería necesario. Por ejemplo, si utilizamos System.Diagnostics.Debug, obtendremos una excepción.

Si queremos desarrollar aplicaciones para la Galileo las APIs Wiring son la opción sólida. Sin embargo,  tenemos un subconjunto de APIs Win32 soportadas que nos permiten poder ejecutar aplicaciones .NET como la vista en este artículo.

Más información