Utilizando agente macOS Hosted para compilar iOS en VSTS

Introducción

Visual Studio Team Services paso a paso ha logrado tener un sistema de builds sencillo de configurar / utilizar y sobretodo muy completo.

Recientemente se añadieron máquinas Hosted Linux que venían a sumarse a las opciones ya disponibles con Windows. Ahora llega el turno de macOS!.

Agente macOS Hosted

Al crear la Build para un proyecto iOS, tenemos disponible una plantilla Xamarin.iOS practicamente preparada. Tras seleccionar la plantilla Xamarin.iOS, llega la hora de seleccionar agente…

Hosted macOS Preview

Y ahora tenemos la opción Hosted macOS Preview!

En el momento de escribir este artículo, las máquinas macOS cuentan con OS X 10.12.6 y todo lo necesario para compilar, no solo proyectos iOS, también Android, etc. Puedes ver un listado completo de contenido preparado e instalado en la máquina macOS en este enlace.

 

Build

¿Personalizar versión herramientas utilizadas?

Podemos seleccionar manualmente la versión a utilizar del SDK de Xamarin. Para ello, antes del paso de compilación, es necesario ejecutar una línea de comandos donde vamos a establecer la versión de Mono asociada con el SDK de Xamarin. Veamos un ejemplo:

/bin/bash –c "sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh 5_4_1"

En el caso anterior se selecciona la versión 5.4.2 (se reemplazan . por _). Puedes ver las versiones a elegir en este enlace.

Si utilizas XCode, quizás también te intere seleccionar la versión. Para hacerlo, antes del paso xcodebuild, se debe ejecutar el siguiente comando:

/bin/bash –c "sudo xcode-select -s /Applications/Xcode_8.3.3.app/Contents/Developer"

Las versiones de XCode que se pueden utilizar se pueden ver en este enlace.

Más información

[Material] Novedades Xamarin del pasado Connect(); 2017 y taller Xamarin

El evento

El pasado 28 de Noviembre, en Sevilla, se organizaba un evento donde repasamos las últimas novedades presentadas en el pasado Connect(); 2017 además de un divertido taller de desarrollo de aplicaciones Xamarin.

El material

Comenzamos el evento repasando novedades Xamarin del Connect(); 2017:

  • Net Embedding
  • Native Forms
  • Live Player
  • Visual Studio App Center
  • XAML Standard
  • Nuevos backends Xamarin.Forms
  • Etc

La presentación utilizada:

Las demos:

Ver GitHub

Continuamos el evento con un taller de 2h de duración. El objetivo fue realizar una aplicación multiplataforma con Xamarin.Forms para Android, iOS, UWP, macOS y Linux utilizando una API Rest. Tras una breve introducción donde repasamos conceptos básicos, comenzamos a crear la aplicación. Vimos una introducción al concepto de enlace a datos, MVVM y su aplicación para acabar realizando a peticiones HTTP para obtener información. Completamos la aplicación conociendo el concepto de navegación y añadiendo una página de detalles.

En cuanto a las demos realizadas, junto a snippets y otro material del taller lo tenéis disponible en GitHub:

Ver GitHub

Más información

[Material Codemotion 2017] Taller Xamarin

El evento

El pasado 24 y 25 de Noviembre, en la universidad San Pablo CEU, tenía lugar el Codemotion 2017. Evento destinado a desarrolladores en España con más de 2000 desarrolladores, más de 30 comunidades técnicas y más de 150 sesiones técnicas.

Codemotion 2017

El material

He tenido la oportunidad de participar este año con un divertido taller de desarrollo con Xamarin.

El objetivo fue realizar una aplicación multiplataforma con Xamarin.Forms para Android, iOS, UWP, macOS y Linux utilizando una API Rest. Tras una breve introducción donde repasamos conceptos básicos, comenzamos a crear la aplicación. Vimos una introducción al concepto de enlace a datos, MVVM y su aplicación para acabar realizando a peticiones HTTP para obtener información. Completamos la aplicación conociendo el concepto de navegación y añadiendo una página de detalles.

Para acabar el taller nos relajamos con un divertido concurso de preguntas, algunos pequeños regalos, preguntas y networking.

La presentación:

En cuanto a las demos realizadas, junto a snippets y otro material lo tenéis disponible en GitHub:

Ver GitHub

Más información

[Quedada Informal] CartujaDotNet & SVQXDG

Quedada múltiple

Desde CartujaDotNet, grupo de usuarios .NET de Sevilla y SVQXDG, grupo de desarrolladores Xamarin de Sevilla, vamos a realizar una quedada informal (la última del año!) para charlar abiertamente sobre tecnologías Microsoft, Xamarin, herramientas utilizadas, intercambiar impresiones, etc. Además, se analizarán las próximas charlas ya planteadas y los eventos confirmados entre otros temas de interés. Al ser quedada de dos grupos diferentes creemos que es una gran oportunidad para conocer, intercambiar e interactuar entre ambos permitiendo a miembros de cada uno conocer a los del otro y tratar otros aspectos.

No hace falta confirmar asistencia, y por supuesto será gratuito.

¿Te apuntas?

A continuación tienes disponible la fecha, hora y lugar:

  • Día: 13 de Diciembre (Miércoles)
  • Horario:  19:00h
  • Lugar: En la Terraza del McDonald’s de Santa Justa

Más información

[Codemotion 2017] Taller de Xamarin

Codemotion 2017

Otro año más, Codemotion se celebrará en Madrid los días 24 y 25 de noviembre en el Campus de Montepríncipe de la Universidad CEU San Pablo. Como en años anteriores, es una cita imprescindible para el mundo del desarrollo de software.

Codemotion 2017

Taller Xamarin

Este año volveré a tener la oportunidad de participar en el evento aunque a diferencia de años anteriores, donde participé con sesiones técnicas, estaré con un taller.

El Sábado 25 de Noviembre, de 12:15h a 14:00h tendremos un taller de desarrollo de aplicaciones multiplataforma con Xamarin. En este Lab veremos como desarrollar aplicaciones nativas multiplataforma para iOS, Android, Windows, macOS y Linux compartiendo la mayor cantidad de código posible utilizando Xamarin.Forms.

Requisitos:

  • Visual Studio 2015 o 2017 para Windows (la versión Community es perfectamente válida) o Visual Studio para macOS.
  • Asegúrate de tener instalado Xamarin.
  • Emuladores de Android.
  • Muchas ganas!

Material:

¿Nos vemos allí?

Más información

[Xamarin.Forms] Utilizando MvvmCross

Introducción

A la hora de desarrollar aplicaciones multiplataforma con Xamarin una de las arquitecturas más utilizadas sin duda alguna es MVVM. Para realizar la implementación contamos con diferentes opciones y algunos frameworks como MvvmCross, una de las opciones más utilizadas con Xamarin Classic.

Tras recibir diferente feedback, muchos tienen la duda…¿y con Xamarin.Forms?.

En este artículo vamos a ver como utilizar MvvmCross con Xamarin.Forms tanto para acciones básicas como asociar vistas con viewmodels así como realizar la navegación entre páginas o el uso de plugins.

¿Lo vemos?

MVVM

Model-View-ViewModel (MVVM) es un patrón de diseño de aplicaciones que permite desacoplar el código de interfaz de usuario del código que no sea de interfaz de usuario.

El patrón MVVM consta de 3 partes:

  • La vista (View) contiene la interfaz de usuario y su lógica.
  • El vista-modelo (ViewModel) contiene la lógica de presentación.
  • El modelo (Model) contiene la lógica de negocio junto a los datos.

La vista interactúa con el vista-modelo mediante enlace a datos (Data Binding) y mediante comandos:

Las ventajas conseguidas utilizando el patrón son significativas:

  • Nos permite dividir el trabajo de manera muy sencilla (diseñadores – desarrolladores)
  • El mantenimiento es más sencillo.
  • Permite realizar Test a nuestro código.
  • Permite una más fácil reutilización de código.

MvvmCross

MvvmCross es un framework que permite aplicar el patrón MVVM, totalmente centrado en Xamarin y el ecosistema móvil. Cuenta con una serie de opciones destinadas a resolver algunas de las necesidades más comunes en el desarrollo móvil además de una gran comunidad que aporta mejoras tanto al propio framework como una diversidad amplia de plugins.

MvvmCross

MvvmCross soporta una gran variedad de plataformas. En el caso de Xamarin.Forms se soporta:

  • PCL
  • Android
  • iOS
  • UWP

En el futuro, al pasar releases estables, se añadirán otras plataformas como Linux (Gtk) o Tizen.

Utilizar MvvmCross en Xamarin.Forms

MvvmCross cuenta con una serie de paquetes NuGet que nos facilitan muchísimo la integración con Xamarin.Forms. Hablamos de los paquetes StarterPack que se encargará de añadir tanto las librerías básicas necesarias como los archivos que nos permitirán utilizar MvvmCross en cada plataforma y de MvvmCross.Forms.

NOTA: A la hora de escribir este artículo, utilizamos la versión 5.4.2 de MvvmCross.

Tras añadir ambos paquetes a todos los proyectos de la solución, comenzamos a editar cada proyecto.

PCL

Comenzamos modificando la aplicación Xamarin.Forms. Para ello, cambiamos:

<FormsApplication xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="HelloMvxForms.Core.App">

</FormsApplication>

Por:

<?xml version="1.0" encoding="utf-8" ?>
<mvx:MvxFormsApplication 
     xmlns="http://xamarin.com/schemas/2014/forms"
     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
     xmlns:mvx="clr-namespace:MvvmCross.Forms.Platform;assembly=MvvmCross.Forms"
     x:Class="HelloMvxForms.Core.App">
</mvx:MvxFormsApplication>

Igualmente, cambiamos App.xaml.cs:

public partial class App : FormsApplication

Por:

public partial class App : MvxFormsApplication

En esta misma clase, vamos a eliminarla línea encargada de estableder la MainPage. Vamos a indicar cual es la vista inicial de la aplicación, a continuación. Al añadir el paquete StarterPack en la PCL se añadió una clase llamada App que vamos a renombrar a MvxApp (puedes renombrarla a CoreApp, u otro nombre):

public class mvxApp : MvvmCross.Core.ViewModels.MvxApplication
{
     public override void Initialize()
     {
          CreatableTypes()
          .EndingWith("Service")
          .AsInterfaces()
          .RegisterAsLazySingleton();

          RegisterNavigationServiceAppStart<MvxMainViewModel>();
     }
}

Utilizamos el método RegisterNavigationServiceAppStart para indicar la viewmodel asociada a una vista que se mostrará como vista de inicio.

Todo listo a nivel de librería portable. Es hora de pasar a proyectos de cada plataforma.

Android

En cada plataforma vamos a contar con una clase llamada Setup encargada de hacer de bootstrapper ed MvvmCross (inicializa dependencias, componentes, etc). La mayoría de las acciones realizadas son virtuales, por lo que permiten personalización.

public class Setup : MvxFormsAndroidSetup
{
     public Setup(Context applicationContext) : base(applicationContext)
     {
     }

     protected override MvxFormsApplication CreateFormsApplication()
     {
          return new Core.App();
     }

     protected override IMvxApplication CreateApp()
     {
          return new Core.MvxApp();
     }

     protected override IMvxTrace CreateDebugTrace()
     {
          return new DebugTrace();
     }
}

Establecemos MvxFormsApplication y la implementación de IMvxApplication de nuestra PCL.

NOTA: Fíjate que el tipo base de la clase setup en Android es MvxFormsAndroidSetup. En la clase Setup añadida por StarterPack, el tipo es MvxAndroidSetup.

Por otro lado, modificamos la actividad principal para cambiar el tipo a MvxFormsAppCompatActivity:

public class MainActivity : MvxFormsAppCompatActivity
{
     protected override void OnCreate(Bundle bundle)
     {
          base.OnCreate(bundle);
          TabLayoutResource = Resource.Layout.Tabbar;
          ToolbarResource = Resource.Layout.Toolbar;
     }
}

iOS

Llegamos a iOS donde tendremos una serie de pasos a realizar, muy similares a Android. Comenzamos por la clase Setup:

public class Setup : MvxFormsIosSetup
{
     public Setup(IMvxApplicationDelegate applicationDelegate, UIWindow window)
     : base(applicationDelegate, window)
     {
     }

     protected override MvxFormsApplication CreateFormsApplication()
     {
          return new Core.App();
     }

     protected override IMvxApplication CreateApp()
     {
          return new Core.MvxApp();
     }

     protected override IMvxTrace CreateDebugTrace()
     {
          return new DebugTrace();
     }
}

También necesitamos modificar la clase AppDelegate:

[Register("AppDelegate")]
public partial class AppDelegate : MvxFormsApplicationDelegate
{
     public override UIWindow Window { get; set; }

     public override bool FinishedLaunching(UIApplication app, NSDictionary options)
     {
          Window = new UIWindow(UIScreen.MainScreen.Bounds);

          var setup = new Setup(this, Window);
          setup.Initialize();

          var startup = Mvx.Resolve<IMvxAppStart>();
          startup.Start();

          LoadApplication(setup.FormsApplication);

          Window.MakeKeyAndVisible();

          return true;
     }
}

Todo listo!

UWP

Al igual que en plataformas anteriores, comenzamos preparando la clase Setup:

public class Setup : MvxFormsWindowsSetup
{
     private readonly LaunchActivatedEventArgs launchActivatedEventArgs;

     public Setup(Windows.UI.Xaml.Controls.Frame rootFrame, LaunchActivatedEventArgs e) : base(rootFrame, e)
     {
          launchActivatedEventArgs = e;
     }

     protected override IMvxApplication CreateApp()
     {
          return new Core.MvxApp();
     }

     protected override IMvxWindowsViewPresenter CreateViewPresenter(IMvxWindowsFrame rootFrame)
     {
          Forms.Init(launchActivatedEventArgs);

          var presenter = new MvxFormsUwpViewPresenter(rootFrame, new MvxFormsApplication());
          Mvx.RegisterSingleton<IMvxViewPresenter>(presenter);

          return presenter;
     }

     protected override MvxLogProviderType GetDefaultLogProviderType() => MvxLogProviderType.None;
}

Modificamos la clase App.xaml.cs donde utilizaremos la clase Setup en el método OnLaunched tras inicializar Xamarin.Forms:

var setup = new Setup(rootFrame, e);
setup.Initialize();

Por último, en la página principal nativa del proyecto UWP:

public MainPage()
{
     InitializeComponent();

     var start = Mvx.Resolve<IMvxAppStart>();
     start.Start();

     var presenter = Mvx.Resolve<IMvxViewPresenter>() as MvxFormsUwpViewPresenter;

     LoadApplication(presenter.FormsApplication);
}

Llega la hora de trabajar con vistas y viewmodels

Las vistas, es decir, páginas en Xamarin.Forms deben extender de MvxContentPage. Por lo que debemos cambiar:

public partial class MvxMainView : ContentPage

Por:

public partial class MvxMainView : MvxContentPage<MvxMainViewModel>

De igual forma, en el XAML de la página, se debe utilizar el namespace:

xmlns:views="clr-namespace:MvvmCross.Forms.Core;assembly=MvvmCross.Forms"

Y definir la página como:

<views:MvxContentPage>

Por defecto, MvvmCross asociada vistas con ViewModels utilizando convención de nombres. Es decir, si tienes una vista llamada SignInView, la ViewModel debe llamarse SignInViewModel.

Cada ViewModel debe ser una clase que herede de MvxViewModel.

Ejemplo básico de uso de Mvx en Xamarin.Forms

Tienes un ejemplo de implementación básico disponible en GitHub:

Ver GitHub

Navegación

MvvmCross utiliza las ViewModels para realizar la navegación. Es decir, la navegación se realiza de ViewModel a Viewmodel en lugar de vista a vista. Tenemos disponible un servicio completo de navegación llamado IMvxNavigationService.

private readonly IMvxNavigationService _navigationService;

public FirstViewModel(IMvxNavigationService navigationService)
{
     _navigationService = navigationService;
}

Contamos con diferentes métodos para gestionar la navegación:

await _navigationService.Navigate<SecondViewModel, string>("parameter");

En el ejemplo anterior, navegamos a una vista llamada SecondView (asociada a la ViewModel llamada SecondViewModel) pasando un parámetro de tipo cadena.

También contamos con diferentes eventos que podemos utilizar en cada ViewModel para la gestión del ciclo de la navegación (navegar, recibir parámetros, etc.):

public override void Prepare(string parameter)
{
     Parameter = parameter;
}
Navegación

Tienes un ejemplo de implementación de navegación con MvvmCross disponible en GitHub:

Ver GitHub

NOTA: Para obtener más información acerca de la navegación en MvvmCross, consulta este enlace.

MvvmCross utiliza Presenter para navegar a vistas en cada plataforma nativa. Actúa como “pegamento” entre vistas y ViewModels. Como podemos deducir de su nombre, un Presenter toma una solicitud de presentación de una ViewModel y decide como presentar la UI. De esa forma, se logra una clara separación entre vistas y ViewModels. Esto también es clave para poder mostrar vistas nativas, Forms o una mezcla de ellas.

NOTA: Se puede cambiar tanto el comportamiento como del servicio de navegación como de Presenter.

Plugins

Haciendo una sencilla búsqueda de “plugin MvvmCross” en NuGet tendremos acceso a una gran variedad de paquetes. Tras añadir el paquete, podemos utilizar el plugin haciendo uso de inyección de dependencias o vía resolución de interfaz. Veamos un ejemplo haciendo uso de Acr.MvvmCross.Plugins.UserDialogs.

Mvx.RegisterSingleton<IUserDialogs>(() => UserDialogs.Instance);

A la hora de utilizar el plugin:

Mvx.Resolve<IUserDialogs>().Alert("Using Mvx Plugins!");
Uso de Plugins

Tienes un ejemplo de uso de plugins MvvmCross disponible en GitHub:

Ver GitHub

MvvmCross añade más funcionalidad en Xamarin.Forms como su propio sistema de enlace a datos (se puede utilizar perfectamente el de Xamarin.Forms) que añade opciones interesantes como Mutiple bindings o converters muy comunes por ejemplo. Sin embargo, en este artículo hemos visto los conceptos básicos necesarios en cualquier aplicación. En futuros artículos, continuaremos profundizando en otros conceptos así como ver otros frameworks y opciones!.

Más información

[Evento Sevilla] Últimas novedades y taller Xamarin

Introducción

Seguimos activos en SVQXDG, grupo de desarrolladores Xamarin de Sevilla, con un nuevo evento!. En esta ocasión, llegamos justo tras el Microsoft Connect(); 2017 donde no nos cabe duda que se presentarán novedades relacionadas con Xamarin. Por ese motivo, nada mejor que agrupar todo en una sesión técnica!. Además, en el mismo evento, y gracias al feedback recibido de otros eventos, vamos a tener un divertido taller donde desarrollaremos desde cero una aplicación móvil para Android, iOS, Windows, macOS y Linux utilizando Xamarin.Forms.

¿Te suena interesante?

El evento

La agenda:

  • 18:00h – 18:10h: Recepción y bienvenida!
  • 18:10h – 19:00h: Novedades Xamarin: Tras un intenso Connect(); 2017, nada mejor que ver las últimas novedades en Xamarin, Xamarin.Forms o Mobile Center para estar al día. Con Javier Suárez.
  • 19:00h – 21:00h: Taller de desarrollo Xamarin: Desarrollaremos una aplicación paso a paso utilizando MVVM y buenas prácticas conectando con un backend. ¿Te animas?. Con Javier Suárez.

Por supuesto, también tendremos momentos para el networking, resolución de dudas e incluso algunos detalles con los asistentes.

Requisitos para el taller:

  • Visual Studio 2015 o 2017 para Windows (la versión Community es perfectamente válida) o Visual Studio para macOS.
  • Asegúrate de tener instalado Xamarin.
  • Emuladores de Android.
  • Muchas ganas!

El lugar

El evento se celebrará en la ETS de Ingeniería Informática. Dirección detallada:

E.T.S. Ingeniería Informática – Universidad de Sevilla, Aula A0.30
Av. Reina Mercedes s/n
Sevilla Se 41012

La fecha

Será el próximo Martes, 28 de Noviembre a las 18:00h (GMT+1). Tendremos una charla de una hora junto a un taller de dos horas.

¿Te apuntas?

Más información

[Xamarin.Forms] Layout Compression

Introducción

La evolución de Xamarin.Forms continua centrada en varios puntos donde destaca con fuerza la búsqueda de rendimiento. Con Xamarin.Forms 2.4.0 se introducía (en Android) los Fast Renderers. El concepto de los Fast Renderers es sencillo, simplificar al máximo los costes de renderizado de cada elemento visual.

Ahora, con la Preview de la versión 2.5.0 recibimos también Layout Compression.

¿Qué es Layout Compression?, ¿cómo afecta en nuestras aplicaciones?.

Layout Compression

Para conocer el concepto de Layout Compression junto con su aporte vamos a utilizar una ejemplo lo más “real” posible. Recientemente preparamos un ejemplo donde realizábamos la interfaz de Netflix con Xamarin.Forms. Este será nuestro ejemplo.

Al realizar un diseño cuidado de una aplicación móvil utilizamos una serie de elementos visuales. Estos elementos visuales, a su vez, en cada platataforma en determinadas ocasiones serán envueltos en paneles y otros elementos visuales para facilitar su uso y gestión. A la hora de renderizar cada vista, se realizan una serie de cálculos de tamaño y posicionamiento de cada elemento. Al contar con mayor complejidad, contaremos con mayor anidación de elementos, mayor número de iteraciones serán necesarias para calcular todo.

Layout Compression permite indicar elementos con anidamiento innecesario y optar a no crear layout. Con esta opción habilitada los layouts se optimizarán en tiempo de compilación permitiendo obtener un mejor rendimiento en tiempo de ejecución.

Con Xamarin Inspector podemos tener una listado completo de la jerarquía que compone la interfaz de usuario. Vamos a aplicar Fast Renderers junto con Layout Compression para hacer una comparativa directa cada vista de la aplicación Xamarin.Forms replicando la interfaz de Netflix.

Vamos a comenzar activando Fast Renderers. Para ello, en el proyecto Android, en su actividad principal:

global::Xamarin.Forms.Forms.SetFlags("FastRenderers_Experimental");

Posteriormente es el momento de analizar la aplicación, identificar Layouts (Grid, StackLayout, AbsoluteLayout, RelativeLayout) para comprimir:

<Grid
     CompressedLayout.IsHeadless="true">
</Grid>

¿Resultados?

Vista de elección de perfil

Partimos en la vista de selección de perfil. Con Xamarin Inspector realizamos un recuento del número total de Renderers necesarios en esta vista llegando a un total de 71 Renderers.

Elección de perfil

Tras activar Fast Renderers y utilizar Layout Compression reducimos el número hasta los 51.

Elección de perfil utilizando Layout Compression
  • Default: 71 Renderers.
  • Layout Compression: 51 Renderers.

Vista principal

Continuamos realizando el mismo proceso con la vista principal de la aplicación. Estamos ante una vista de mayor complejidad. El número total de Renderers sube hasta los 223.

Vista principal

Y utilizando Xamarin.Forms 2.5.0 Pre-Release bajamos a las 169.

Vista principal usando Layout Compression
  • Default: 223 Renderers.
  • Layout Compression: 169 Renderers.

Vista de detalles

Llegamos a la vista más compleja con 296 Renderers.

Detalles de una película

Que reducimos hasta 229 utilizando Layout Compression.

Detalles utilizando Layout Compression
  • Default: 296 Renderers.
  • Layout Compression: 229 Renderers.

A tener en cuenta

La compresión de un Layout hace que se no cree su Renderer por lo tanto, no funcionarían aspectos relacionados con el Layout como:

  • Color de fondo.
  • Gestos.
  • Transformaciones.
  • Etc.

Revisa con cuidado si haces uso de TapGestureRecognizer u  otra característica para decidir si puedes comprimir o no el Layout.

Conclusiones

En este ejemplos concreto (hemos intentado utilizar un ejemplo con cierta complejidad a nivel visual) la media de reducción de Renderers es de un 24%.  Se exactamente que te estas preguntando, ¿como impactará en mi aplicación?, ¿será más rápida?. La respuesta es si. Antes que nada ten en cuenta que afecta a Android e iOS. En nuestro ejemplo, la aplicación si se nota más fluida aunque todo dependerá de diversos factores como el dispositivo, versión del sistema operativo, etc. En un Oneplus 3 (Snapdragon 820, 6GB de RAM) apenas se notan diferencias mientras que con un Nexus 5 (Snapdragon 800, 2 GB de RAM) si se nota mejora al cargar las páginas.

¿Y a ti que te parece?, ¿has realizado pruebas?. Te animo a compartir tus resultados en los comentarios de la entrada!

Más información

[Xamarin.Forms] .NET Standard 2.0 y Entity Framework Core

Introducción

Cuando desarrollamos aplicaciones móviles, en una gran cantidad de ocasiones, vamos a necesitar trabajar y gestionar datos. Podemos necesitar sencillas clave-valor para gestionar la configuración de la aplicación, o bien, datos más complejos relacionales utilizando una base de datos local como SQLite o Realm.

A la hora de trabajar con datos, una opción muy familiar para desarrolladores .NET es Entity Framework.

¿Podemos utilizar Entity Framework desde una aplicación Xamarin?, ¿qué limitaciones encontramos?.

En este artículo, vamos a ver paso a paso como llegar a utilizar Entity Framework Core en una aplicación Xamarin.Forms.

NOTA: Este artículo se focaliza en aprender como utilizar Entity Framework Core en una aplicación Xamarin. No tiene como objetivo dar a conocer conceptos básicos de Entity Framework.

Entity Framework Core

Entity Framework es un ORM (object-relational mapper) que permite a los desarrolladores trabajar con una base de datos utilizando objetos .NET. Con un largo recorrido, la primera versión de Entity Framework aparecía en verano de 2008, ha ido evolucionando en base a las necesidades de desarrolladores. Como proyecto Open Source, ha contado con importantes contribuciones.

En verano de 2016, llega .NET Core y junto al mismo algunas tecnologías relacionadas, como Entity Framework Core.

Cuando hablamos de Entity Framework Core nos referimos a una versión ligera, extensible y además multiplataforma de Entity Framework.

NOTA: Si cuentas con experiencia con Entity Framework encontrarás Core muy familiar. Sin embargo, recuerda que es una versión más ligera y que hay opciones no disponibles (por ejemplo, lazy loading).

Con el lanzamiento de .NET Standard 2.0 Preview para UWP junto con el lanzamiento de Entity Framework Core 2.0, podemos desarrollar aplicaciones móviles para iOS, Android y UWP con EF y SQLite. A pesar de no contar con todas las opciones de Entity Framework, la versión Core es muy interesante por diversos motivos:

  • Fácil de arrancar.
  • Se integra bien con Linq.
  • Se puede utilizar en diferentes plataformas gracias a .NET Core (Android, macOS, Linux, etc.).

NOTA: Puedes ver una tabla comparativa ente EF Core y EF 6 en este enlace.

Comenzamos

Partimos de una aplicación Xamarin.Forms creada con la plantilla disponible:

Nueva App Xamarin.Forms

Librería .NET Standard

Nuestro objetivo es tener una librería .NET Standard, una librería con una especificación de APIs .NET diseñada para estar disponible en todos los runtimes .NET. Esta librería actuará de forma similar a una PCL, será el lugar donde añadiremos el código común compartido de todas las aplicaciones móviles además de la lógica de Entity Framework Core.

Tenemos varias opciones para tener la librería. Podemos crear una librería .NET Standard nueva que reemplazará a la PCL (la acabaremos borrando):

Nueva librería .NET Standard

O podemos editar la PCL para convertirla en una librería .NET Standard.

<Project Sdk="Microsoft.NET.Sdk">
     <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
     <PackageTargetFallback>$(PackageTargetFallback);portable-win+net45+wp8+win81+wpa8</PackageTargetFallback>
     </PropertyGroup>
</Project>

Vamos a utilizar .NET Standard 2.0:

.NET Standard 2.0

NOTA: Para poder utilizar Entity Framework 2.0, es necesario utilizar una .NET Standard versión 2.0. Necesitas tener instalado .NET Core SDK 2.0.

Añadir Microsoft.EntityFrameworkCore.Sqlite

Tenemos que añadir paquete NuGet de Entity Framework en nuestros proyectos. Para ello, hacemos clic derecho en la gestión de paquetes NuGet de la solución y añadimos Microsoft.EntityFrameworkCore.Sqlite.

Microsoft.EntityFrameworkCore.Sqlite

Trabajando con Entity Framework

Tras añadir el paquete de Entity Framework podemos comenzar a trabajar!.  Si ya has trabajado previamente con Entity Framework no te será desconocido el contexto DbContext.

En Entity Framework llamamos contexto a la puerta de enlace entre el modelo que utilizamos y el framework que se encarga de conectar con al base de datos y de realizar el mapeo de las diferentes operaciones con comando de datos. DbContext será el responsable de:

  • Conexiones de base de datos.
  • Operaciones de datos tales como consultas y persistencia.
  • Seguimiento de cambios.
  • Mapeo de datos.
  • Gestión de transacciones.
  • Etc.

Vamos a desarrollar una aplicacación que permita tomar notas.

Comenzamos definiendo nuestros Modelos que se encargarán de definir el esquema de nuestra base de datos.

Modelos

public class TodoItem
{
     [Key]
     public int Id { get; set; }
     public string Name { get; set; }
     public string Notes { get; set; }
     public bool Done { get; set; }
}

Crear el contexto

A continuación, nos aseguramos que nuestra clase TodoItem es parte de nuestro DbContext. Definimos el contexto:

class DatabaseContext : DbContext
{
     public DbSet<TodoItem> TodoItems { get; set; }

     public DatabaseContext()
     {
          this.Database.EnsureCreated();
     }

     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
     {
          var dbPath = DependencyService.Get<IDatabaseService>().GetDatabasePath();
          optionsBuilder.UseSqlite($"Filename={dbPath}");
     }
}

De igual forma a cuando trabajamos directamente con SQLite por ejemplo, necesitamos código específico por plataforma para acceder a la ruta de la base de datos adecuada.

Android

public class DatabaseService : IDatabaseService
{
      public string GetDatabasePath()
      {
           return Path.Combine(
           System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), 
           AppSettings.DatabaseName);
      }
}

iOS

public class DatabaseService : IDatabaseService
{
     public string GetDatabasePath()
     {
         return Path.Combine(Environment.GetFolderPath(
         Environment.SpecialFolder.MyDocuments), 
         "..", 
         "Library", 
         AppSettings.DatabaseName);
     }
}

NOTA: Es importante utilizar el servicio de dependencia de Xamarin.Forms parar resolver la dependencia específica de la plataforma donde se ejecuta la aplicación:

[assembly: Dependency(typeof(DatabaseService))]

Insertar nuevos registros

La clase DbSet<TEntity> representa una colección para una entidad dada dentro del modelo y es la vía de entrada a las operaciones de la base de datos. Las clases DbSet<TEntity> se agregan como propiedades al DbContext.

Para insertar nuevos registros a la colección representada por el DbSet, utilizamos el método DbSet.Add:

_context.TodoItems.Add(item);

Esto añade los cambios al DbSet en memoria, es necesario utilizar el método SaveChanges para actualizar la base de datos.

_context.SaveChanges();

Actualizar registro

Para actualizar una entidad, se deben realizar los cambios necesarios en el valor de la propiedad o propiedades de la misma y utilizar el método Update junto a  SaveChanges.

_context.TodoItems.Update(todoItem);

Obtener información desde la base de datos

La forma más común utilizada para obtener varias entidades es utilizar el método ToList:

public IList<TodoItem> GetAll()
{
     return _context.TodoItems.ToList();
}

Si lo que se busca es recuperar una sola instancia de una entidad, se puede usar el método First o Single, dependiendo de si espera que haya más de una fila que coincida con los criterios.

Eliminar registro

Por último, para eliminar registros, utilizamos el método Remove disponible en la clase DbSet además de, SaveChanges.

public void Remove(TodoItem item)
{
     _context.TodoItems.Remove(item);
     _context.SaveChanges();
}

Puedes descargar el ejemplo realizado desde GitHub:

Ver GitHub

Recuerda, cualquier comentario, duda o pregunta es bienvenida en los comentarios de la entrada.

Más información

[Xamarin.Forms] Probando Live XAML, actualizando XAML al vuelo!

Productividad trabajando con XAML

Conseguir aplicaciones con una interfaz rica, elegante y perfectamente adaptada a cada plataforma requiere un proceso de repetición de cambio, compilación, depuración y vuelta a repetir.

Contamos con opciones interesantes para solventar este problema como Previewer, Gorilla Player o Xamarin Live Player. Ya vimos todas las herramientas anteriores, ahora, nos llega el turno de probar otra opción muy interesante, Live XAML.

Live XAML

Live XAML es una extensión disponible para Visual Studio tanto en Windows como en macOS que se encarga de inyectar el código necesario para reaccionar ante cualquier cambio de XAML. Esto significa que, con tu aplicación en modo depuración en un emulador o en un dispositivo, puedes ver al vuelo cualquier cambio en XAML.

La instalación

Desde la página oficial de la herramienta podemos descargar una extensión para Visual Studio disponible tanto para Windows como para macOS.

Tras descargar e instalar la extensión todo listo. Uno de los grandes puntos positivos de la herramienta es su facilidad de uso, tras instalar, para utilizar la herramienta en cada proyecto bastará con indicarle a la herramienta que añada paquete NuGet en la librería compartida llamado LiveXAML o bien, añadir el paquete a mano.

LiveXAML NuGet

Comenzamos con un ejemplo sencillo

Partimos de un proyecto básico, la plantilla vacía de Xamarin.Forms. Lanzamos el proyecto en depuración.

Comenzamos con las pruebas más sencillas posibles, cambiar propiedades básicas como el texto o el color del Label añadido por defecto:

Continuamos con otros requisitos básicos al desarrollar en aplicaciones, el uso de recursos y estilos.

La herramienta se comporta sin problemas al utilizar recursos tanto a nivel de elemento, como a nivel de página como a nivel de aplicación.

Probamos posibilidades más complejas

Tiene buena pinta, pero…¿y será válido con aplicaciones más complejas?. Recientemente, en el blog vimos un recopilatorio de ejemplos Xamarin.Forms con intefaz atractiva. Entre ese recopilatorio se encuentra un ejemplo que intenta reproducir la interfaz de Netflix en Xamarin.Forms. Vamos a utilizarla.

Podemos realizar pruebas con enlace a datos en sus difentes modos.

La cabecera con transparencias haciendo uso de Custom Renderer, efecto Parallax, el uso de controles personales para listados, etc. Estamos trabajando con una página relativamente compleja. Podemos realizar cambios al vuelo y realizar pruebas directamente. Por ejemplo, cambios en el tamaño de la cabecera y pruebas con el efecto Parallax:

Puedes descargar el ejemplo de Netflix desde GitHub:

Ver GitHub¿Aumentamos la complejidad?

¿Funcionaría con .NET Standard?, ¿y con librerías personalizadas?. Pasamos a continuación a ver un ejemplo haciendo uso de .NET Standard, SkiaSharp y la librería Microcharts que aporta diversas gráficas de gran belleza y posibilidades creadas con SkiaSharp.

Creamos un pequeño control que añade animaciones a la gráfica. Ajustar la velocidad de la animación, tamaño de fuentes, elementos, etc. Sería fantástico poder aplicar estos cambios al vuelo, sin necesidad de parar, recompilar, esperar el despliegue, etc., ¿verdad?.

Fíjate que en la cabecera de la gráfica hacemos también uso de efectos. Aplicamos un efecto que añade sombras al texto.

Puedes descargar el ejemplo desde GitHub:

Ver GitHub

Conclusiones

Tras todas las pruebas que has podido ver anteriormente (más muchas otras), los resultados son excelentes. No he encontrado errores de renderizado, comunicación o funcionamiento en general de la herramienta. Así que, debemos destacar su fácil instalación y su buen hacer. Tampoco es necesario aprender nada nuevo ya que todo se integra en Visual Studio y con el flujo habitual. Eso si, recuerda, estamos ante una herramienta que tiene coste.

Más información