[Xamarin.Forms] Aplicación móvil y Cosmos DB

Introducción

En una gran variedad de aplicaciones móviles se requiere almacenar datos. Podemos almacenar datos locales con opciones como SQLite o Realm; o en la nube con diferentes opciones. Entre las opciones disponibles en Azure, ha llegado con fuerza Cosmos DB.

En este artículo vamos a ver paso a paso como utilizar una base de datos de documentos Cosmos DB en una aplicación Xamarin.Forms. Realizaremos una aplicación que permita tomar, modificar y eliminar notas.

Cosmos DB

Una base de datos de documentos Azure Cosmos DB es una base de datos No SQL que proporciona acceso a información (JSON) de forma rápida, con alta disponibilidad, escalable y con replicación global.

Una base de datos de documentos en Azure Cosmos DB es un contenedor lógico para colecciones de documentos y usuarios. Puede contener cero o más colecciones. A su vez, cada colección de documentos puede tener un nivel de rendimiento diferente en base a la frecuencia de acceso. Cada colección de documentos cuenta con documentos JSON. A medida que se añaden documentos a una colección, Cosmos DB indexa automáticamente.

NOTA: Para pruebas y desarrollo, una base de datos de documentos se puede utilizar con un emulador. El emulador permite probar de forma local sin necesidad de suscripción Azure ni costes.

Crear Azure Cosmos DB

Accede al portal de Azure. Desde el menú lateral, Databases > Azure Cosmos DB:

Nueva Azure Cosmos DB

A continuación, debemos rellenar el formulario de creación:

Crear CosmosDB Azure

Donde:

  • API: Existen cuatro opciones diferentes: Gremlin (graph), MongoDB, SQL (DocumentDB), y tablas (key-value). En nuestro ejemplo usaremos DocumentDB.

Preparando el proyecto

Partiendo de una aplicación Xamarin.Forms, lo primero que necesitamos para realizar la integración con Azure Cosmos DB es añadir el paquete NuGet DocumentDB Client Library a la solución.

Microsoft.Azure.DocumentDB

La interfaz ded usuario

En nuestra aplicación contaremos con dos vistas, un listado de notas y una vista de detalles para crear, editar o eliminar una nota específica.

Comenzamos definiendo la vista principal. Tendremos un listado de notas:

<ListView 
     ItemsSource="{Binding Items}" 
     SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
     RowHeight="60">
     <ListView.ItemTemplate>
          <DataTemplate>
               <ViewCell>
                    <ViewCell.View>
                         <StackLayout 
                              Padding="12,0,12,0" 
                              HorizontalOptions="FillAndExpand">
                              <Label 
                                   Text="{Binding Notes}"
                                   FontSize="Medium"
                                   FontAttributes="Bold"/>
                              <Label 
                                   Text="{Binding Date}"
                                   FontSize="Small"/>
                         </StackLayout>
                     </ViewCell.View>
                </ViewCell>
           </DataTemplate>
      </ListView.ItemTemplate>
</ListView>

A parte de definir como se visualizará cada elemento de la lista definiendo el DataTemplate establecemos la fuente de información, propiedad ItemsSource enlazada a propiedad de la ViewModel que obtendrá los datos de la base de datos.

Además del listado, debemos añadir en nuestra interfaz una forma de poder insertar nuevas tareas. Para ello, una de las opciones más habituales e idóneas es utilizar una Toolbar.

 <ContentPage.ToolbarItems>
      <ToolbarItem
           Name="Add" 
           Command="{Binding AddCommand}">
           <ToolbarItem.Icon>
                <OnPlatform 
                     x:TypeArguments="FileImageSource"
                     Android="plus" 
                     iOS="plus.png" />
           </ToolbarItem.Icon>
      </ToolbarItem>
 </ContentPage.ToolbarItems>

La clase Device es muy importante en Xamarin.Forms ya que nos permite acceder a una serie de propiedades y métodos con el objetivo de personalizar la aplicación según dispositivo y plataforma. Además de permitirnos detectar el tipo de dispositivo, podemos detectar la plataforma gracias a la enumeración Device.OS o personalizar elementos de la interfaz gracias al método Device.OnPlatform entre otras opciones. En nuestro ejemplo, personalizamos el icono de añadir en base a la plataforma.

Nuestra interfaz:

Listado de notas

Enlazamos la View con la ViewModel estableciendo una instancia de la ViewModel a la propiedad BindingContext de la página.

BindingContext = App.Locator.NoteItemViewModel;

En la ViewModel contaremos con una propiedad pública para definir el listado de notas, además de la nota seleccionada (utilizada para la navegación):

private ObservableCollection<Note> _items;
private Note _selectedItem;

public ObservableCollection<Note> Items
{
     get { return _items; }
     set
     {
          _items = value;
          OnPropertyChanged();
     }
}

public Note SelectedItem
{
     get { return _selectedItem; }
     set
     {
          _selectedItem = value;
          _navigationService.NavigateTo<NoteItemViewModel>(_selectedItem);
     }
}

Añadimos elementos con un comando disponible en la ViewModel.

public ICommand AddCommand
{
     get { return _addCommand = _addCommand ?? new Command(AddCommandExecute); }
}

Al pulsar y lanzar el comando, navegaremos a la vista de detalles.

_navigationService.NavigateTo<NoteItemViewModel>(todoItem);

Si creamos un nuevo elemento pasaremos como parámetro una nueva entidad de tipo Note, en caso de seleccionar una existente, pasaremos el seleccionado disponible en la propiedad SelectedItem.

Definimos la interfaz de la vista de detalles:

<StackLayout 
     VerticalOptions="StartAndExpand" 
     Padding="20">
     <Label 
          Text="Notes" />
     <Entry 
          Text="{Binding Notes}"/>
     <Button 
          Text="Save"
          Command="{Binding SaveCommand}"/>
     <Button 
          Text="Delete"
          Command="{Binding DeleteCommand}"/>
     <Button 
          Text="Cancel"
          Command="{Binding CancelCommand}"/>
</StackLayout>

El resultado:

Detalles

Para enlazar la información de un elemento seleccionado, debemos capturar la información enviada en la navegación.

¿Cómo capturamos el elemento seleccionado en la navegación?. Utilizamos el método OnAppearing para capturar el parámetro NavigationContext.

public override void OnAppearing(object navigationContext)
{
     var note = navigationContext as Note;

     if (note != null)
     {
          Id = note.Id;
          Notes = note.Notes;
     }

     base.OnAppearing(navigationContext);
}

En cuanto a cada botón, cada uno de ellos estará enlazado a un comando:

private ICommand _saveCommand;
private ICommand _deleteCommand;
private ICommand _cancelCommand;

public ICommand SaveCommand
{
     get { return _saveCommand = _saveCommand ?? new Command(SaveCommandExecute); }
}

public ICommand DeleteCommand
{
     get { return _deleteCommand = _deleteCommand ?? new Command(DeleteCommandExecute); }
}

public ICommand CancelCommand
{
     get { return _cancelCommand = _cancelCommand ?? new Command(CancelCommandExecute); }
}

private void SaveCommandExecute()
{
 
}
 
private void DeleteCommandExecute()
{
 
}
 
private void CancelCommandExecute()
{
 
}

Consumiendo la base de datos Cosmos DB

Vamos a crear un servicio que contenga toda la lógica necesaria para trabajar con Cosmos DB desde nuestra aplicación Xamarin.Forms. DocumentClient encapsula la lógica necesaria relacionada con credenciales y conexiones con Azure Cosmos DB.

Comenzamos creando una instancia de DocumentClient:

var client = new DocumentClient(new Uri(EndpointUri), PrimaryKey);

En el constructor del cliente debemos pasar tanto la URL de conexión como la clave primaria. Ambos valores se pueden obtener desde el portal de Azure.

Clave Primaria

Con el cliente preparado, tenemos todo lo necesario para trabajar con Azure Cosmos DB.

Creando base de datos

De las primeras acciones a realizar sera la creación de la base de datos. Recuerda, una base de datos de documentos es un contenedor lógico para colecciones de documentos. Podemos crearla tanto desde el portal Azure como por código. Utilizaremos el método CreateDatabaseIfNotExistsAsync:

await _client.CreateDatabaseIfNotExistsAsync(new Database
{
     Id = databaseName
});

El método crea la base de datos con el identificador establecido en Id o bien, devuelve la base de datos si ya existe. Se devuelve Task<ResourceResponse<Database>> que contiene un código de estado, ideal para verificar si la base de datos se ha creado o si se ha obtenido una previamente existente.

Crear colección de documentos

Una colección de documentos es un contenedor de documentos JSON. Al igual que la base de datos, podemos crearlo en el portal o por código. Por código utilizamos CreateDocumentCollectionIfNotExistsAsync:

 await _client.CreateDocumentCollectionIfNotExistsAsync(
      UriFactory.CreateDatabaseUri(databaseName),
      new DocumentCollection
      {
           Id = collectionName
      });

El método requiere dos parámetros obligatorios (también cuenta con otros opcionales):

  • Nombre de base de datos: Especificado como Uri.
  • DocumentCollection: Representa una colección de documentos. Especificamos el nombre utilizando la propiedad Id.

El método crea la colección si no existe o devuelve la colección si ya existía previamente.

Obtener documentos de una colección

El contenido de una colección se puede obtener ejecutando una consulta. Podemos crear consultas utilizando el método CreateDocumentQuery. Por ejemplo:

var query = _client.CreateDocumentQuery<T>(_collectionLink) 
     .AsDocumentQuery();

while (query.HasMoreResults)
{
     items.AddRange(await query.ExecuteNextAsync<T>());
}

De esta forma podemos obtener todos los documentos de una colección específica. En el método CreateDocumentQuery se puede especificar vía Uri la colección de datos a la que conectar.

El método AsDocumentQuery convierte el resultado de la creación de la consulta en un objeto de tipo IDocumentQuery<T>. ExecuteNextAsync vamos obteniendo los resultados de la siguiente página (mientras exista más valores HasMoreResults).

Crear documento

Crear documentos cuyo contenido es en formato JSON se pueden insertar en una colección utilizando CreateDocumentAsync:

await _client.CreateDocumentAsync(_collectionLink, item);

Se especifica vía Uri la colección en la que se va a insertar el documento y el argumento de tipo objeto. El objeto es la información a insertar.

Eliminar documento

Se pueden eliminar documentos utilizando DeleteDocumentAsync:

await _client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(DatabaseName, CollectionName, id));

Se especifica vía Uri el documento de la colección a eliminar.

NOTA: También es posible eliminar toda una colección de documentos con DeleteDocumentCollectionAsync e incluso una base de datos completa con DeleteDatabaseAsync.

Llegados a este punto, ¿qué nos falta?. Sencillo, utilizar la lógica para interactuar con Azure Cosmos DB desde nuestras ViewModels. Crearemos la base de datos y la colección al navegar a la primera vista. En esta primera vista obtendremos todos los documentos creados (nuestras notas!). Desde la vista de detalles, en cada comando enlazado a la interfaz, utilizaremos la lógica para crear o eliminar notas.

Tenéis el código fuente disponible e GitHub:

Ver GitHubTe animo a descargar el ejemplo y realizar tus propias pruebas. Hasta aquí llegamos!. Recordad que podéis dejar cualquier comentario, sugerencia o duda en los comentarios.

Más información

[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

[Xamarin.Forms] Extensiones de marcado

Introducción

Xamarin.Forms añade una capa de abstracción en la capa de UI que nos permite definir la misma una única vez para todas las plataformas. Podemos definir esta interfaz con código C# o XAML.

A la hora de trabajar con la interfaz en XAML con casi toda seguridad utilizarás alguna extensión de marcado.

Extensiones de marcado

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.

Existen extensiones de marcados muy usadas y conocidas como Binding o StaticResource. Pero… ¿conoces todas las extensiones disponibles y su uso?.

En este artículo, vamos a conocer todas las extensiones básicas existentes.

Binding

Estamos ante la expresión de marcado más utilizada. Cuando el código XAML se encuentra con un literal entre llaves, lo interpreta y no se limita a mostrarlo como si fuera un simple texto. En este caso hace una evaluación encontrando la palabra reservada Binding, lo que indica que debe enlazar el valor de una propiedad. Pero…¿cómo sabe dónde se encuentra la propiedad?, todos los elementos que componen la interfaz de usuario descienden de una importante jerarquía de clases base que otorgan funcionalidad vital.

Contamos con la propiedad BindingContext que actúa como contexto de datos del elemento. Si la propiedad fuese nula en el elemento, se buscaría de forma ascendente en la jerarquía de elementos. Es decir, si la propiedad BindingContext del elemento visual es nula, buscará en el elemento padre inmediato, etc.

Veamos un ejemplo.

public class Person
{
     public string Name { get; set; }
     public string SurName { get; set; }
}

Establecemos el BindingContext:

BindingContext = person;

A la hora de utilizar el Binding:

<Label Text={Binding Name}" />

En un enlace a datos, la palabra reservada Mode indica la forma en la que se comporta el mismo. En Xamarin.Forms contamos con los siguientes modos:

  • OneWay: es el valor por defecto. Indica que el enlace se realiza en un único sentido, de lectura. Aunque el valor del elemento visual cambie, no viajará hasta el  ViewModel.
  • OneWayToSource: en un único sentido generalmente de la View al ViewModel.
  • TwoWay: en este caso el enlace es bidireccional. La View toma el valor del ViewModel, pero si lo editamos en la vista, el cambio se envía de vuelta al ViewModel.
  • Default: el modo utilizado por defecto, que como hemos visto es OneWay.
<Entry Text={Binding Username, Mode=TwoWay}" />

Por otro lado, en ocasiones, lo que se desea mostrar en la interfaz de usuario no equivale al valor enlazado. Podríamos extender modelos añadiendo más propiedades para este propósito, pero no es lo ideal. Para solventar este problema contamos con las propiedades de formateo de texto.

<Label Text="{Binding Count, StringFormat='Number of Records = {0:N}'}"/>

Veamos otro ejemplo:

<Label Text="{Binding Date, StringFormat='{0:dd MM yyyy}'}" />

Converters

En ocasiones, el valor enlazado no es el deseado. Por ejemplo, tenemos enlazado un valor de tipo DateTime pero deseamos mostrar una cadena de texto al usuario con un formato de fecha aplicado. Justo para este objetivo, tenemos los TypeConverters.

En lugar de extender nuestros modelos con más y más valores, los Converters nos permiten transformar unos valores a otros directamente desde XAML.

<Label Text="{Binding Date}" />

En este caso veríamos el resultado de lanzar el método ToString del DateTime. Podemos crear un Converter:

public class DatetimeToStringConverter : IValueConverter
{
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
     {
          if (value == null)
               return string.Empty;

          var datetime = (DateTime)value;
          return datetime.ToLocalTime().ToString("g");
     }

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
     {
          throw new NotImplementedException(); 
     }
}

El Converter es una clase que herede de la interfaz IValueConverter, se implementa el método Convert y ConvertBack. Para utilizar el converter se debe definir primero como recurso:

<ResourceDictionary>
 <local:DatetimeToStringConverter x:Key="DateTimeConverter" />
</ResourceDictionary>

Y posteriormente, utilizar la palabra reservada Converter para acceder al mismo:

<Label Text="{Binding Date, Converter={StaticResource DateTimeConverter}}" />

NOTA: Se suelen utilizar los Converters para transformaciones más complejas.

TemplateBinding

Con la versión 2.1.0 de Xamarin.Forms se introdujo el concepto de Control Templates y también el de TemplateBinding. Un TemplateBinding es similar a un Binding, excepto que el origen de un TemplateBinding siempre se establece automáticamente en el padre de la vista de destino que posee la plantilla de control.

<ControlTemplate x:Key="PageTemplate">
     <StackLayout>
          <Label Text="{TemplateBinding BindingContext.HeaderText}" /> 
          <ContentPresenter />
     </StackLayout>
</ControlTemplate>

StaticResource

En cada elemento visual podemos definir un conjunto de recursos. Utilizamos ResourceDictionary para a gestión de recursos. Con StaticResource podemos acceder a objetos estáticos definidos como recursos y disponibles en tiempo de compilación.

<ContentPage.Resources>
 <ResourceDictionary>

     <Style x:Key="ErrorLabelStyle" TargetType="Label">
          <Setter Property="TextColor" Value="Red" />
     </Style>

</ResourceDictionary>
</ContentPage.Resources>

<Label Text="Hello!" Style="{StaticResource ErrorLabelStyle}" />

DynamicResource

Esta extensión de marcado es sumamente similar a la anterior pero cuenta con una gran diferencia. DynamicResource permite acceder a recursos añadidos en tiempo de ejecución. Es decir, si un recurso es eliminado / añadido en un diccionario de recursos en tiempo de ejecución, DynamicResource es tu extensión.

var errorLabelStyle = new Style(typeof(Label));

errorLabelStyle.Setters.Add(new Setter() 
{ 
     Property = Label.BackgroundColorProperty, Value = Color.Red 
});

this.Resources.Add(errorLabelStyle);

Tras añadir dinámicament el tiempo de ejecución el estilo, accedemos al mismo:

<Label Text="Hello!" Style="{DynamicResource ErrorLabelStyle}" />

Otras extensiones de marcado

Existen estensiones de marcado intrínsecas de XAML y soportadas en archivos XAML de Xamarin.Forms.

x:Array

Se pueden definir arrays directamente en XAML gracias a esta extensión de marcado.

<x:Array x:Key="StringArray" Type="{x:Type x:String}">
     <x:String>Hello</x:String>
     <x:String>World</x:String>
</x:Array>

x:Null

Extensión de marcado que permite establecer valor nulo. Si una propiedad cuenta con soporte a valores no nulos y se desea establecer por defecto a nulo, {x:Null} es la extensión de marcado idónea.

x:Reference

Los enlaces de datos se pueden definir para vincular propiedades de dos elementos visuales en la misma página. En este caso, se establece el  BindingContext del objeto de destino utilizando la extensión de marcado x: Reference.

<StackLayout>
     <Slider 
          x:Name="slider"
          Maximum="100" />
     <Label 
          BindingContext="{x:Reference slider}"
          Text="{Binding Value,
          StringFormat='The angle is {0:F0} degrees'}" />
 </StackLayout>

x:Static

A pesar de lo que pueda dar a pensar, x:Static y StaticResource NO son iguales. Mientras que StaticResource nos permite acceder a un objeto definido en un diccionario de recursos, x:Static nos permite el acceso a una propiedad o constante estática.

<Label 
     Text="Awesome!"
     TextColor="{x:Static Color.Blue}" />

NOTA: Esta extensión de marcado es más potente de lo que pueda parecer. También puedes acceder a campos o propiedades estáticas de tu propio código. Si se cuenta con una clase estática con constantes, se podrían utilizar.

x:Type

Permite establecer el tipo del objeto utilizando {x:Type Class}.

Extensiones de marcado personalizadas

Llegamos hasta aquí!. Cuando se comienza a desarrollar en XAML algunas son muy utilizadas y bien conocidas pero no así con todas. Xamarin.Forms también permite crear nuevas extensiones de marcado personalizadas aunque es algo que veremos en un próximo artículo.

Hasta la próxima!

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] Trucos y consejos rendimiento Xamarin.Forms

Introducción

Recientemente, en SVQXDG, tuvimos un interesante evento Xamarin relacionado con el rendimiento en Xamarin.Forms. Tras recibir feedback por diferentes redes sociales, meetup o vía correo, ante el interés en diferentes partes geográficas hemos decidido…repetir el evento online!

El evento

¿Sabes el ciclo de vida de un Layout?, ¿qué opciones de Layout son más óptimas?, ¿cómo afectan los Bindings al rendimiento y como tratarlos?, ¿rendimiento en listados?, ¿fast renderers?. A todas esas preguntas y a otras tantas, intentaremos dar solución en esta sesión online!.

El evento será el próximo Sábado, 17 de Junio a las 12:00h (GMT+1).

¿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