[Xamarin.Forms] Extensiones de marcado personalizadas

Introducción

Las extensiones de marcado son una forma de obtener un valor que no sea específico de tipo primitivo o un objeto XAML. Mediante la apertura y cierre de llaves, se define en su interior lo que se conoce como extensión de marcado.

En este artículo, vamos a conocer como crear nuestras propias extensiones de marcado.

RECUERDA: Ya vimos en un artículo anterior el concepto de extensión de marcado así como las extensiones de marcado disponibles.

 

Extensiones de marcado personalizadas

Las extensiones de marcado implementan la interfaz IMarkupExtension. Esta interfaz sólo cuenta con un método a implementar:

public object ProvideValue(IServiceProvider serviceProvider)

Cuando se realiza el análisis del código XAML y el compilador encuentra una extensión de marcado, se lanza este método antes de establecer el valor de la extensión.

Crear extensiones

Vamos a realizar una de las extensiones de marcado más sencillas posibles con el objetivo de centrarnos a fondo en los conceptos clave de la extensión. Nuestra extensión nos permitirá utilizar colores RGB estableciendo directamente los valores para rojo, verde y azul.

En el método ProvideValue, por defecto, no obtenemos valores con IServiceProvider. Por lo tanto, para obtener los valores necesarios en nuestra extensión (rojo, verde y azul) vamos a necesitar utilizar propiedades.

public class RGBColor : IMarkupExtension
{
     public int Red { get; set; }

     public int Green { get; set; }

     public int Blue { get; set; }

     public object ProvideValue(IServiceProvider serviceProvider)
     {
          return Color.FromRgb(Red, Green, Blue);
     }
}

Creamos una clase que hereda de IMarkupExtension, implementamos el método ProvideValue que se lanzará a la hora de evaluar la expresión. Gracias a propiedades capturamos los valores deseados. La lógica del método ProvideValue se encarga de crear el valor devuelto deseado, un color.

Todo listo!

Utilizar extensiones

Utilizar la extensión es sencillo. Necesitamos acceder a la misma, por lo tanto, debemos declarar el espacio de nombres en XAML en el lugar a utilizar:

xmlns:extensions="clr-namespace:CustomMarkupExtension.Extensions;assembly=CustomMarkupExtension"

Y utilizarlo:

<Label
     Text="Test"
     TextColor="{extensions:RGBColor Red=255, Green=0, Blue=255}"
     BackgroundColor="{extensions:RGBColor Red=200, Green=100, Blue = 0}" />

Fíjate que todo el código queda bastante simple y muy legible. Tenéis el código fuente del ejemplo utilizado disponible en GitHub:

Ver GitHub

Mediante la implementación de IMarkupExtension podemos crear nuestras propias extensiones de marcado. Las extensiones de marcado personalizadas nos dan una forma sencilla y potente de ejecutar código, realizar validaciones y conversiones de valores antes de establecer el valor de una propiedad.

Más información

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

[Tips and Tricks] Librería para reutilizar estilos entre diferentes Apps Xamarin.Forms

Introducción

En toda aplicación móvil la apariencia visual es vital. Cada vez es mayor el esfuerzo depositado a la hora de crear aplicaciones atractivas a la par que intuitivas y en muchos casos conseguir una imagen única que diferencia a la Aplicación del resto es prioritario. Por este motivo, debemos de contar con opciones sencillas de poder personalizar los distintos elementos que componen la interfaz.

Los estilos permitir definir múltiples propiedades visuales de elementos de la interfaz de forma reutilizable.

En ocasiones, se desarrollan diferentes aplicaciones para la misma empresa o marca comercial. Hablamos de aplicaciones totalmente diferentes pero que sin duda, van a compartir algunos elementos visuales específicos como colores, logos e incluso algunos estilos visuales (forma de botones, etc.).

¿Cómo lograr reutilizar estilos entre diferentes aplicaciones Xamarin.Forms?

ResourceDictionary

Los recursos XAML son objetos que podemos reutilizar más de una vez. Hablamos desde un sencillo color o tamaño de fuente, a el uso de estilos. Los diccionarios de recursos o ResourceDictionaries permiten definir una zona donde definir recursos.

Podemos definir recursos a nivel de elemento visual, a nivel de página e incluso a nivel de Aplicación.

¿Cómo definimos recursos en otra librería?.

Buscamos tener una librería con recursos, estilos y/o converters que sea compartida entre diferentes aplicaciones:

Librería

  • Aplicación 1
  • Aplicación 2

Creando una librería

Comenzamos creando una librería portable (PCL). En Visual Studio, nuevo proyecto de tipo PCL:

PCL

Añadimos el paquete NuGet de Xamarin.Forms. Y a continuación, añadimos una página de tipo ContentPage:

ContentPage

Renombramos ContentPage por ResourceDictionary en la página recien creada.

Todo listo!.

Bastará con añadir recursos, estilos o converters. Ejemplo:

<Style x:Key="SharedButtonStyle" TargetType="Button">
     <Setter Property="BackgroundColor" Value="Red" />
     <Setter Property="Rotation" Value="45" />
</Style>

Utilizando la librería

Para utilizar la librería desde una aplicación Xamarin.Forms, comenzamos añadiendo la referencia a la librería desde la aplicación:

Referencias

Añadida la referencia, llega el paso de mayor importancia. A nivel de Aplicación, tenemos la posibilidad de añadir recursos en un diccionario de recursos:

<Application.Resources>
     <ResourceDictionary>

     </ResourceDictionary>
</Application.Resources>

Vamos a utilizar la propiedad MergedWith para añadir a los estilos de la aplicación, los estilos de la librería:

<Application
     xmlns:styles="clr-namespace:Styles;assembly=Styles">
    <Application.Resources>
        <ResourceDictionary MergedWith="styles:ButtonStyles">

        </ResourceDictionary>
    </Application.Resources>
</Application>

El resultado:

Estilos desde otra librería!

Realizamos una combinación de estilos a nivel de elemento visual, página, Aplicación e incluso desde otra librería (último botón). Tenéis el código fuente del ejemplo utilizado disponible en GitHub:

Ver GitHubRecuerda, cualquier tipo de duda o sugerencia es bienvenida en los comentario del artículo.

Más información

[Material] Xamarin Dev Days Málaga 2017

El evento

El pasado sábado 24 de Junio, tenía lugar en Málaga el Xamarin Dev Days. Una jornada con varias sesiones técnicas, taller, regalos y mucho networking.

El resultado fue un fantástico día de desarrollo Xamarin con muchas preguntas, ayuda y tiempo para charlar entre todos rodeados de un café o unas pizzas.

El material

Pude participar en el evento con una de las sesiones. Nos centramos en el desarrollo de aplicaciones móviles multiplataforma utilizando Xamarin y aprovechando la potencia de Azure.

Tras las sesiones, realizamos un muy divertido taller donde paso a paso, desarrollamos una aplicación Xamarin.Forms aplicando MVVM y accediendo a una Azure Mobile App.

En cuanto a las demos técnicas realizadas, las tenéis disponible en GitHub:

Ver GitHub

Un día genial de comunidad con grandes momentos que esperamos repetir sin duda!

Más información

[Material] Xamarin Dev Days Madrid 2017

El evento

El pasado sábado 10 de Junio, tenía lugar en Madrid el Xamarin Dev Days. Una jornada con varias sesiones técnicas, taller, regalos y mucho networking.

El resultado fue un fantástico día de desarrollo Xamarin con muchas preguntas, ayuda y tiempo para charlar entre todos rodeados de un café o unas pizzas.

El material

Pude participar en el evento con una de las sesiones. Nos centramos en el desarrollo de aplicaciones móviles multiplataforma utilizando Xamarin.Forms:

Comenzamos por una introducción de conceptos básicos, primera demo  y terminamos repasando todas las últimas novedades como Forms Embedding o las futuras novedades de Xamarin.Forms 3.0.

Tras las sesiones, realizamos un muy divertido taller donde paso a paso, desarrollamos una aplicación Xamarin.Forms aplicando MVVM y accediendo a una Azure Mobile App.

En cuanto a las demos técnicas realizadas, las tenéis disponible en GitHub:

Ver GitHub

Un día genial de comunidad con grandes momentos que esperamos repetir sin duda!

Más información

[Evento Online] Introducción a Xamarin.IoT

El evento

¿Tienes pensado instalar o tienes instalado Linux en tu dispositivo IoT, usando la flexibilidad y potencia de C#?.

Xamarin IoT permite a los desarrolladores crear aplicaciones de consola, usando IDE’s de primer nivel como son Visual Studio, Visual Studio for Mac/Linux, además de poder ejecutar y debuguear tu aplicación favorita de un dispositivo remoto.

Una charla intensa, donde si el tiempo nos lo permite, intentaremos abordar todos los puntos:

  • Presentación e introducción Xamarin.IoT.
  • Setup de dispositivo.
  • Arquitectura.
  • Ejemplos de uso.
  • Hermes.Mqtt Client/Server.
  • Azure Sql Database + Entity framework.
  • IoTSharp.Components.

A todos estos puntos y a todas las preguntas posibles intentaremos dar solución en esta sesión online!.

El ponente

Tendré la compañía en esta ocasión de Jose Medrano. Jose es desarrollador de software y actualmente trabaja en Microsoft formando parte del equipo de Xamarin Profiler & Xamarin IoT.

Jose Medrano

La fecha

El evento será el próximo Martes, 27 de Junio.

  • 19:00 en España
  • 13:00 en Colombia
  • 12:00 en México Centro
  • 13:30 en Venezuela
  • 15:00 en Chile continental

¿Te apuntas?

Más información

[Evento Online] Xamarin Hol – Módulo V: Mobile DevOps con Visual Studio Team Services y HockeyApp

Introducción

Hace ya un tiempos os hablé del concurso de desarrollo de aplicaciones Xamarin. Microsoft quiere animarte a lanzarte a crear Apps participando en el Hackathon Online que se organizará los próximos 16, 17 y 18 de Junio. Antes de llegar al Hackathon, se está realizando una toma de contacto con Xamarin además de resolver dudas basándonos en el Hand On Lab de Pierce Boggan, “Spent”. 

Spent

En este taller, exploraremos las características y funcionalidad de Xamarin.Forms desde una aplicación para hacer el seguimiento de los gastos.

El evento

Tras publicar los cinco módulos correspondientes al Hand On Lab y tras varios eventos online donde se han repasado los cuatro primeros módulos con grandes compañeros de la comunidad, llega el turno de quinto módulo centrado en procesos de integración continua y distribución continua utilizando VSTS y HockeyApp.

En el evento veremos como crear Builds para aplicaciones Xamarin desde VSTS y desde Mobile Center, como distribuir betas desde HockeyApp o cómo obtener analíticas de uso, información de errores, etc.

¿Te apuntas?

Más información

[Xamarin.Forms] Accesibilidad

Introducción

La accesibilidad es un factor de vital importancia que por suerte, es tenida en cuenta cada vez con mayor frecuencia y peso en desarrollos web, móviles, etc.

Cuando hablamos de accesibilidad en el desarrollo, nos referimos al concepto de diseñar interfaces de usuario que funcionen de forma correcta ante las diferentes características de visualización y asistencia de entrada. La gestión de alto contraste, zoom, tamaño de fuente o la lectura de pantalla son opciones que permiten el acceso de muchos usuarios a nuestras aplicaciones.

Las principales plataformas móviles del mercado, es decir, iOS, Android y Windows cuentan con APIs para permitir a los desarrolladores crear aplicaciones accesibles.

Xamarin.Forms nos permite crear aplicaciones multiplataforma nativas compartiendo interfaces de usuario gracias a su capa de abstraccion.

¿Cómo creamos aplicaciones accesibles con Xamarin.Forms?

Soporte a accesibilidad en aplicaciones Xamarin.Forms

En versiones previas de Xamarin.Forms para añadir opciones de accesibilidad, requeríamos de Custom Renders. Acceder a APIs nativas para acceder a opciones de accesibilidad. Con la llegada de los efectos, todo se simplificó pemitiendo crear efectos con acceso a APIs nativas de forma más sencilla.

Con la llegada de Xamarin.Forms 2.3.5 se añade soporte directo a APIs de accesibilidad.

Accesibilidad en Xamarin.Forms

Opciones de accesibilidad

Xamarin.Forms incluye diferentes opciones de accesibilidad disponibles en la clase AutomationProperties y disponibles como propiedades adjuntas. Estas propiedades se encargan de añadir en cada plataforma el uso correcto de las diferentes opciones de accesibilidad.

  • AutomationProperties.HelpText
  • AutomationProperties.IsInAccessibleTree
  • AutomationProperties.LabeledBy
  • AutomationProperties.Name

HelpText

Es un valor de tipo cadena que se utilizará para sintetizar en voz.

AutomationProperties.HelpText

En cada plataforma se utilizará una propiedad corespondiente a las APIs nativas:

  • Android: Hint
  • iOS: AccesibilityHint
  • Windows: AutomationProperties.HelpTextProperty

IsInAccesibleTree

Propiedad de tipo bool que indica si el elemento es accesible.

AutomationProperties.IsInAccessibleTree

En cada plataforma:

  • Android: Focusable
  • iOS: IsAccesibilityElement
  • Windows: AutomationProperties.AccesibilityViewProperty

LabeledBy

Esta propiedad permite que otro elemento visual defina información de accesibilidad. Así, podemos utilizar la información de otro elemento para ayudar a describir.

AutomationProperties.LabeledBy

Internamente, cada plataforma utiliza las siguientes propiedades:

  • Android: SetLabelFor
  • iOS: No se mapea a ninguna propiedad.
  • Windows: AutomationProperties.LabeledByProperty

Name

Es el nombre del elemento.

AutomationProperties.Name

En cada plataforma:

  • Android: ContentDescription
  • iOS: AccesibilityLabel
  • Windows: AutomationProperties.NameProperty

Veamos un ejemplo:

<StackLayout>
     <Label 
          x:Name="UsernameLabel"
          Text="Username"/>
     <Entry      
          AutomationProperties.Name="UsernameEntry"
          AutomationProperties.IsInAccessibleTree="True" 
          AutomationProperties.LabeledBy="{x:Reference UsernameLabel}"
          AutomationProperties.HelpText="Insert Username" 
          Placeholder="Insert Username"/>
</StackLayout>

El ejemplo se encuentra disponible en GitHub:

Ver GitHub

Consejos accesibilidad

En general, a la hora de gestionar la accesibilidad en tu aplicación, deberíamos tener en cuenta los siguientes detalles:

  • Haz pruebas de tu interfaz con los esquemas de color en modo contraste alto.
  • Etiqueta los elementos de la interfaz con textos descriptivos utilizando las APIs de accesibilidad para permitir la lectura de la pantalla en cada plataforma.
  • Recuerda etiquetar también botones e imágenes de la aplicación con una descripción accesible.
  • Excluye elementos de decoración innecesarios!.
  • En muchas ocasiones las aplicaciones móviles gestionan diferentes estados sólo con elementos visuales. Por ejemplo, al realizar la carga de elementos, mostramos un indicador visual para indicar progreso y fin. Recuerda agregar en estos indicadores específicos de accesibilidad. También se pueden añadir refuerzos acústicos.
  • Ante contenido multimedia recuerda añadir descripciones legíbles y permitir acceder de forma sencilla a los botones de gestión del contenido.
  • Si la aplicación está localizada en diferentes idiomas, recuerda localizar también todas las descripciones de accesbilidad añadidas.
  • Cada plataforma cuenta con herramientas diferentes de narración. Android cuenta con opciones como Google TalkBack, iOS cuenta con VoiceOver y Windows con Narrator. Cada plataforma funciona de forma única a pesar de todas ellas contar con opciones similares. Es recomendable hacer pruebas en todas las plataformas donde nuestra aplicación puede funcionar.

Más información

[Xamarin.Forms] Forms Embedding

Introducción

Cuando tratamos el desarrollo de aplicaciones Xamarin hay algunas preguntas importantes a resolver. Entre ellas, destaca con fuerza, ¿Xamarin Classic o Xamarin.Forms?. Es una pregunta habitual en diferentes charlas de diferentes temáticas, en formación y a la hora de afrontar un nuevo proyecto. La respuesta suele requerir algo de tiempo para analizar muchos aspectos como la interfaz de la aplicación, conocimiento del equipo, etc. Pero…¿y si nos quedamos con las dos opciones?.

¿Qué es Forms Embedding?

Con Xamarin.Forms podemos acceder a cualquier API nativa, podemos crear nuevos controles y acceder a la plataforma con Custom Renders o efectos e incluso podemos incrustar controles nativos con Native Views. Forms Embedding es el nombre asignado a la posibilidad de incrustar cualquier ContentPage de Xamarin.Forms en una aplicación nativa de Android, iOS o Windows.

Forms Embedding

Estará disponible entre el conjunto de novedades de la próxima versión 3.0 de Xamarin.Forms:

  • Mejoras en rendimiento (Fast Renderers y Layout Compression).
  • Nuevas plataformas (GTK#, WPF o MacOS).
  • Native Embedding.
  • XAML Standard.
  • Etc.

Suena interesante, ¿verdad?. Aquellos desarrollos utilizando Xamarin Classic (también llamado Native) se pueden beneficiar de Xamarin.Forms para compartir vistas comunes. Podemos combinar lo mejor de las dos opciones!

Haciendo Forms Embedding ahora

A pesar de llegar como opción en Xamarin.Forms 3.0, podemos hacer Forms Embedding ahora mismo. Sólo necesitamos un poco más de código. Veamos como hacerlo!

Creamos una aplicación Xamarin Classic utilizando una PCL y la plantilla Maestro y detalle:

Nueva App

Gracias a la plantilla tenemos rápidamente una aplicación Xamarin Classic completa:

Plantilla Maestro y detalle

Añadimos un nuevo proyecto, una librería portable (PCL) donde vamos a añadir las vistas Xamarin.Forms totalmente compartidas entre todas las plataformas.

PCL

Un ejemplo muy común de vista que suele tener mucho sentido tener totalmente compartida, es una vista de configuración. Añadimos una nueva ContentPage llamada SettingsView:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FormsEmbedding.Forms.Views.SettingsView">
    <ContentPage.Content>
        <StackLayout>
            <Label Text="Welcome to Xamarin Forms Settings!" />
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Label Grid.Column="0" Grid.Row="0" Text="Settings 1" />
                <Switch Grid.Column="1" Grid.Row="0" HorizontalOptions="End" />
                <Label Grid.Column="0" Grid.Row="1" Text="Settings 2" />
                <Switch Grid.Column="1" Grid.Row="1" HorizontalOptions="End" />
                <Label Grid.Column="0" Grid.Row="2" Text="Settings 3" />
                <Switch Grid.Column="1" Grid.Row="2" HorizontalOptions="End" />
                <Label Grid.Column="0" Grid.Row="3" Text="Settings 4" />
                <Switch Grid.Column="1" Grid.Row="3" HorizontalOptions="End" />
                <Label Grid.Column="0" Grid.Row="4" Text="Settings 5" />
                <Switch Grid.Column="1" Grid.Row="4" HorizontalOptions="End" />
            </Grid>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

El resultado:

SettingsView

¿Cómo utilizamos esta página desde Android, iOS y Windows?. Lo primero es crear una aplicación Application de tipo Xamarin.Forms.

public class FormsApp : Application
{
     public FormsApp(Type page = null)
     {
         SetMainPage(page);
     }

     public void SetPage(Type page)
     {
         if (page == null) 
         {
             MainPage = new ContentPage();
             return;
         }

         MainPage = (Page)Activator.CreateInstance(page);
     }

     public static Page GetPage<T>() where T : Page 
     {
         return Activator.CreateInstance<T>();
     }
}

Establecemos como MainPage la página pasada como parámetro.

Android

Xamarin.Forms utiliza una actividad de tipo FormsAppCompatActivity donde se realiza la inicialización de Xamarin.Forms y se realiza la carga de la App. Vamos a crear una actividad nueva donde realizar la inicialización requerida de Forms así como,  recibir la vista Xamarin.Forms a mostrar y cargarla en la App.

public class FormsActivity : FormsAppCompatActivity
{
     public static bool IsFormsInitialized;

     protected override void OnCreate(Bundle bundle)
     {
         base.OnCreate(bundle);

         var view = Intent.Extras.GetString("View");
         var viewPath = typeof(FormsApp).Namespace + ".Views." + view;
         var viewType = typeof(FormsApp).Assembly.GetType(viewPath);

         if (!IsFormsInitialized)
         {
             global::Xamarin.Forms.Forms.Init(this, bundle);
             IsFormsInitialized = true;
         }

         LoadApplication(new FormsApp(viewType));
     }
}

Fíjate que esperamos un parámetro View donde tenemos el nombre de la página Xamarin.Forms a mostrar. Partiendo del nombre, obtenemos el tipo de la página y realizamos la inicialización.

Con todo esto, posiblemente tengas ya en mente como vamos a realizar la navegación a la página de Xamarin.Forms:

var intent = new Intent(this, typeof(FormsActivity));
intent.PutExtra("View", "SettingsView");
StartActivity(intent);

Navegamos a una nueva actividad, nuestra actividad FormsActivity, pasandole como parámetro la página Xamarin.Forms a mostrar.

El resultado:

Android

 

iOS

En el caso de iOS nuestro objetivo será tener un UIViewController al que poder navegar partiendo de la ContentPage de Xamarin.Forms:

var settingsViewControler = FormsApp.GetPage<SettingsView>().CreateViewController();
await PresentViewControllerAsync(settingsViewControler, true);

En Xamarin.Forms contamos con una extensión de páginas que cuenta con el método CreateViewController que nos hace la mayor parte del trabajo. Obtenemos la página de Forms, convertimos a UIViewController y navegamos!

iOS

Windows

Llegamos a UWP. En este caso, Xamarin.Forms, utiliza una vista nativa de tipo FormsWindowsPage donde se realiza la carga de la App. Creamos en el proyecto UWP una nueva página nativa:

<forms:WindowsPage
    x:Class="FormsEmbedding.UWP.Pages.FormsWindowsPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:FormsEmbedding.UWP.Pages"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:forms="using:Xamarin.Forms.Platform.UWP"
    mc:Ignorable="d">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    </Grid>
</forms:WindowsPage>

Reemplazamos el tipo de Page a FormsWindowsPage utilizando el namespaces correspondiente. En el código asociado de la página realizaremos dos acciones necesarias (como ya hicimos en otras plataformas). Por un lado, inicializaremos la aplicación Xamarin.Forms:

var formsApp = new FormsApp()
LoadApplication(formsApp);

Y por otro lado, estableceremos la página principal:

_formsApp.SetPage(e.Parameter as Type);

Con todo preparado, para navegar a una página de Xamarin.Forms bastaría con:

Frame.Navigate(typeof(FormsWindowsPage), typeof(SettingsView));

Navegar a la nueva página creada pasando como parámetro el tipo de la página de Forms. También podríamos pasar el nombre de la página como cadena y tras recuperarlo obtener el tipo como hicimos en Android.

El resultado:

UWP

NOTA: En todos los proyectos nativos hemos añadido la última versión del paquete estable de Xamarin.Forms.

El ejemplo de esta versión se encuentra disponible en GitHub:

Ver GitHub

Xamarin.Forms 3.0

Hoy día ya podemos probar una versión Preview de Xamarin.Forms 3.0. Para ello, debemos añadir https://www.myget.org/F/xamarinforms-dev/api/v3/index.json como nuevo origen de paquetes.

Nuevo origen de paquetes

De esta forma tendrás acceso a los paquetes previos de Xamarin.Forms 3.0:

Paquetes NuGet Xamarin.Forms 3.0

Con el paquete previo de la versión 3.0 nos llega el soporte oficial a Forms Embedding o lo que es lo mismo, todo  lo necesario para incrustar páginas Xamarin.Forms en aplicaciones nativas de forma rápida y muy sencilla.

Volvemos a crear un nuevo proyecto en una PCL donde vamos a añadir las páginas Xamarin.Forms a compartir, de igual forma a como hicimos previamente.

Veamos como utilizar la página en cada plataforma.

Android

En Android se ha añadido una extensión de página de modo que podemos hacer:

var settings = new SettingsView().CreateFragment(this);

Creamos una instancia de la página Xamarin.Forms y utilizamos el método CreateFragment para crear un Fragment Android que podemos añadir como contenido de nuestra aplicación Xamarin.Android.

iOS

En el caso de iOS nuestro objetivo será tener un UIViewController al que poder navegar partiendo de la ContentPage de Xamarin.Forms:

var settingsViewControler = FormsApp.GetPage<SettingsView>().CreateViewController();
await PresentViewControllerAsync(settingsViewControler, true);

En Xamarin.Forms contamos con una extensión de páginas que cuenta con el método CreateViewController que nos hace la mayor parte del trabajo. Si, es sumamente parecido a lo que ya vimos previamente.

Windows

Y llegamos a UWP donde al igual que en el resto de plataformas, se utiliza una extensión de página para obtener un FrameworkElement a partir de la página Xamarin.Forms.

var settingsView = new SettingsView().CreateFrameworkElement();

Muy muy sencillo, ¿cierto?.

El ejemplo de esta versión se encuentra disponible en GitHub:

Ver GitHub

Más información

Probando Xamarin Live Player

Introducción

Cuando hablamos de desarrollos web e incluso desarrollos para escritorio los tiempos de despliegue y ejecucición junto con los requisitos a cumplir son extremadamente ajustados.

Cuando hablamos de movilidad, la cosa es algo diferente…

En el caso de Xamarin.iOS necesitamos contar con una conexión con Xamarin Mac Host para compilar y desplegar en el dispositivo o en el simulador.

En el caso de Xamarin.Android necesitamos contar con SDK de Android, instalar emuladores x86 para reducir tiempos de despliegue, etc.

¿Y si contámos con una opción más rápida y directa que reduzca a mínimos los requisitos para desplegar y probar la App?

Xamarin Live Player

Xamarin Live Player llega como opción para permitir editar al vuelo la aplicación y ver esos cambios reflejados directamente en el dispositivo. Se trata de una aplicación móvil (realizada con Xamarin y disponible en las diferentes Stores) que permite correr nuestro código sin necesidad de emuladores o un cable USB para desplegar la App.

Xamarin Live Player

La idea es:

  1. Tener una App Xamarin en el IDE (Visual Studio para Windows o MacOS).
  2. Emparejar un dispositivo con la App Xamarin Live Player.
  3. Lanzar la App en el dispositivo.
  4. Poder hacer cambios al vuelo!

De esta forma, se reducen tiempos y requisitos necesarios para desplegar y probar las Apps. No se necesita conexión con Mac, tener instalados emuladores, etc.

Preparando el entorno

Suena bien, ¿verdad?. Vamos a preparar el entorno y todo lo necesario.

1. Obtener la App

Comenzamos descargando la App móvil. Xamarin Live Player se encuentra disponible tanto para iOS como para Android.

Xamarin Live Player App

2. Obtener Visual Studio 2017 Preview en Windows

Para poder utilizar Xamarin Live se necesita tener instalado:

  • Visual Studio 2017 15.3 Preview
  • Xamarin Updater

La elección de canales alpha, beta o estable que teníamos en versiones anteriores de Visual Studio no está disponible en Visual Studio 2017. En su lugar, tenemos dos canales de distribución de Visual Studio:

  • Release
  • Preview

Para tener acceso a las Previews, podemos descargar una versión de Visual Studio Preview.

Descargar Visual Studio 2017 Preview

NOTA: La Preview disponible al escribir estas líneas es la 15.3.

Durante el proceso de instalación, se puede introducir un Installation Nickname que nos permite distinguir la versión Preview de la versión de VisualStudio estable. De esta forma podemos tener instalados varias instancias diferentes.

Varios Visual Studios!

Tras tener Visual Studio 2017 Preview instalado, debemos contar con Xamarin Updater disponible en Visual Studio Marketplace.

Xamarin Updater

 

2. O para Mac

En el caso de utilizar MacOS se necesita tener macOS 10.12 o superior y tener instalado Visual Studio para Mac.

Actualizar Visual Studio para Mac

Emparejando dispositivos

Todo listo para probar. Para asegurar que lo tenemos todo listo, en Visual Studio debes encontrar la opción Xamarin Live Player en la opción Herramientas:

Xamarin Live Player en el menu de Herramientas

Con Xamarin Live Player preparado, al desplegar econtraremos la opción Live Player:

Live Player

La primera vez que realizamos el despliegue, aparecerá la siguiente pantalla:

Emparejar dispositivo

Para emparejar el dispositivo, debemos abrir la aplicación Xamarin Live Player previamente instalada y utilizar la cámara para capturar el código QR o bien, introducir en el IDE el código que aparecerá en la App.

Tras emparejar, todo preparado para comenzar a utilizar la herramienta!

Probándolo todo!

Ejecutamos la aplicación y en breves instantes:

App Xamarin.iOS desde Windows sin Build Host!

Estamos utilizando una de las demos disponibles en Xamarin Live Player, una aplicación Xamarin.iOS ejecutada en un iPhone sin utilizar Mac Build Host.

NOTA: En esta demo tenenemos el iPhone conectado por USB al equipo de desarrollo con Windows para hacer Screen Mirroring. No es necesario conectar el dispositivo por cable para utilizar Xamarin Live.

Con la aplicación lanzada podemos interaccionar con ella:

La App en funcionamiento

Y podemos depurarla exactamente igual a cuando la desplegamos de forma habitual:

Depurando

Por otro lado, encontramos la opción  Live Run Current View.

Live Run Current View

Esta opción permite realizar cambios directamente al vuelo. Todo se irá compilando y ejecutando de forma continua en el dispositivo por lo que podremos ir aplicando cambios al vuelo y ver sus resultados de forma inmediata, sin recompilar todo ni esperas.

Limitaciones

No, la aplicación no es perfecta en estos momentos, ni funcionará todo. Recuerda que estamos aún ante una Preview. Entre las limitaciones encontramos:

  • Algunas características de Storyboards en iOS no están soportadas.
  • Algunas características del sistema no se soportan por la App. Sin embargo, opciones muy comunes como el uso de la cámara si están soportadas.

Entre las limitaciones más importantes tenemos:

  • No se soportan archivos AXML (diseño de interfaces en Android).
  • No se soportan archivos iOS XIB.
  • Soporte limitado a reflexión. Ojo, porque hay muchos paquetes NuGets que se pueden ver afectados como el uso de SQLite.

¿Ya no necesito un MAC?

Xamarin Live Player nos permite probar nuestras aplicaciones Xamarin Native o Xamarin.Forms en dispositivos Android e iOS. Si, podemos desplegar aplicaciones Xamarin.iOS a un dispositivo iOS sin necesidad de Mac Build Host (conexión con un Mac).

Entonces, ¿ya no necesitamos un Mac?.

¿Ya no necesitamos un Mac?

A pesar de no dudar de la evolución y soporte a más y más opciones en Xamarin Live Player, de momento cuenta con limitaciones a tener en cuenta.

Por otro lado, es necesario el Mac para el acceso a otras herramientas como diseñadores visuales de Storyboards, o bien, para crear paquetes, etc. Recuerda, necesitamos un Mac para compilar y crear el paquete.

En definitiva, tenemos una nueva opción que nos ayuda y acelera en el desarrollo e incluso, si, nos puede reducir la necesidad de conexiones con el Build Host pero no evita la necesidad del Mac en el desarrollo iOS.

Más información

Puedes descargar una presentación con un resumen de todo el artículo:

Enlaces: