Análisis detallado de Android

Anatomía de una aplicación de Xamarin.Android

En la captura de pantalla siguiente se muestra el contenido de la solución. Este es el Panel de solución, que contiene la estructura de directorios y todos los archivos asociados a la solución:

Panel de solución

Se ha creado una solución denominada Phoneword y se ha colocado dentro el proyecto de Android Phoneword.

Observe los elementos situados dentro del proyecto y fíjese en cada carpeta y su finalidad:

  • Propiedades: Contiene el archivo AndroidManifest.xml, que describe todos los requisitos de la aplicación de Xamarin.Android, incluidos el nombre, el número de versión y los permisos. La carpeta Propiedades también contiene AssemblyInfo.cs, un archivo de metadatos de ensamblado .NET. Se recomienda que incluya en este archivo información básica sobre la aplicación.
  • Referencias: Contiene los ensamblados necesarios para compilar y ejecutar la aplicación. Si expande el directorio Referencias, verá referencias a ensamblados .NET, como System, System.Core y System.Xml, así como una referencia al ensamblado Mono.Android de Xamarin.
  • Activos: Contiene los archivos que la aplicación necesita para ejecutarse, como fuentes, archivos de datos locales y archivos de texto. Se puede acceder a los archivos incluidos aquí mediante la clase generada Assets. Para obtener más información sobre los activos de Android, consulte la guía de Xamarin Using Android Assets (Uso de activos de Android).
  • Recursos: Contiene recursos de la aplicación, como cadenas, imágenes y diseños. Puede tener acceso a estos recursos en el código mediante la clase generada Resource. La guía Android Resources (Recursos de Android) proporciona información detallada sobre el directorio Recursos. La plantilla de aplicación también incluye una guía concisa sobre los recursos en el archivo AboutResources.txt.

Recursos

El directorio Recursos contiene tres carpetas denominadas drawablelayout y values, así como un archivo denominado Resource.designer.cs.

Los elementos se resumen en la tabla siguiente:

  • drawable: El directorio drawable contiene recursos que se pueden dibujar, como imágenes y mapas de bits.
  • mipmap: El directorio mipmap contiene archivos drawable para distintas densidades de los iconos de iniciadores. En la plantilla predeterminada, el directorio drawable contiene el archivo del icono de la aplicación, Icon.png.
  • layout: El directorio layout contiene archivos de Android Designer (.axml), que definen la interfaz de usuario de cada pantalla o actividad. La plantilla crea un diseño predeterminado denominado Main.axml.
  • values: Este directorio contiene archivos XML que almacenan valores simples, como cadenas, enteros y colores. La plantilla crea un archivo para almacenar valores de cadena denominado Strings.xml.
  • Resource.designer.cs: También conocido como la clase Resource, este archivo es una clase parcial que contiene los identificadores únicos asignados a cada recurso. Lo crean automáticamente las herramientas de Xamarin.Android y se vuelve a generar según sea necesario. Este archivo no se debe editar manualmente, ya que Xamarin.Android sobrescribirá todos los cambios manuales que se realicen en él.

Aspectos básicos de la arquitectura y la aplicación

Las aplicaciones de Android no tienen un solo punto de entrada, es decir, no hay una única línea de código en la aplicación que el sistema operativo llame para iniciar la aplicación. En su lugar, una aplicación se inicia cuando Android crea una instancia de una de sus clases, durante lo cual Android carga el proceso completo de la aplicación en la memoria.

Esta función exclusiva de Android puede ser muy útil al diseñar aplicaciones complicadas o interactuar con el sistema operativo Android. Pero estas opciones también hacen que Android sea complejo cuando se trabaja con un escenario básico como la aplicación Phoneword. Por este motivo, la exploración de la arquitectura de Android se divide en dos partes. En esta guía se analiza una aplicación que usa el punto de entrada más común de una aplicación de Android: la primera pantalla. En Hello, Android Multiscreen se exploran todas las complejidades de la arquitectura de Android a medida que se describen las distintas formas de iniciar una aplicación.

Escenario de Phoneword: empezar con una actividad

Cuando se abre la aplicación Phoneword por primera vez en un emulador o un dispositivo, el sistema operativo crea la primera actividad. Una actividad es una clase especial de Android que se corresponde con una sola pantalla de la aplicación y es responsable de dibujar y activar la interfaz de usuario. Cuando Android crea la primera actividad de la aplicación, carga toda la aplicación:

Carga de actividad

Dado que no existe una progresión lineal en una aplicación de Android (puede iniciar la aplicación desde varios puntos), Android tiene una sola manera de realizar un seguimiento de las clases y los archivos que componen una aplicación. En el ejemplo de Phoneword, todas las partes que componen la aplicación se registran con un archivo XML especial denominado manifiesto de Android. La función del manifiesto de Android consiste en realizar un seguimiento del contenido, las propiedades y los permisos de una aplicación y comunicárselos al sistema operativo Android. La aplicación Phonewordpuede considerarse como una sola actividad (pantalla) y una colección de archivos auxiliares y de recursos unidos mediante el archivo de manifiesto de Android, como se muestra en el diagrama siguiente:

Aplicaciones auxiliares de recursos

En las secciones siguientes se exploran las relaciones entre las distintas partes de la aplicación Phoneword, para que entienda mejor el diagrama anterior. Esta exploración comienza con la interfaz de usuario y analiza cuestiones como los archivos de diseño y Android Designer.

Interfaz de usuario

Main.axml es el archivo de diseño de la interfaz de usuario de la primera pantalla de la aplicación. La extensión .axml indica que se trata de un archivo de Android Designer (AXML significa XML de Android). El nombre Main es arbitrario desde el punto de vista de Android, es decir, el archivo de diseño podría tener otro nombre. Cuando se abre Main.axml en el IDE, aparece el editor visual de los archivos de diseño de Android, denominado Android Designer:

Android Designer

En la aplicación Phoneword, el identificador de TranslateButton está establecido en @+id/TranslateButton:

Configuración del identificador de TranslateButton

Al establecer la propiedad id de TranslateButton, Android Designer asigna el control TranslateButton a la clase Resource y le asigna un identificador de recurso de TranslateButton. Esta asignación de un control visual a una clase hace posible la ubicación y el uso de TranslateButton y otros controles en el código de la aplicación. Esto se explicará con más detalle cuando se analice el código que activa los controles. Lo único que necesita saber por ahora es que la representación del código de un control está vinculada a la representación visual del control en el diseñador mediante la propiedad id.

Vista Código fuente

Todos los elementos definidos en la superficie de diseño se traducen a XML para que Xamarin.Android los pueda usar. Android Designer proporciona una vista de código fuente que contiene el XML que se generó desde el diseñador visual. Para ver este código XML, cambie al panel de código fuente situado en la parte inferior izquierda de la vista del diseñador, como se muestra en la siguiente captura de pantalla:

Vista Código fuente de Designer

Este código fuente XML debe contener el texto (grande), el texto sin formato y los dos elementos de botón. Para obtener más información sobre Android Designer, consulte la guía Designer Overview (Introducción al diseñador) de Xamarin Android.

Ya hemos visto las herramientas y los conceptos relacionados con la parte visual de la interfaz de usuario. Ahora veremos el código que activa la interfaz de usuario mientras exploramos las actividades y el ciclo de vida de la actividad.

Actividades y ciclo de vida de actividad

La clase Activity contiene el código que activa la interfaz de usuario. La actividad es responsable de responder a la interacción del usuario y de crear una experiencia de usuario dinámica. En esta sección se presenta la clase Activity, se describe el ciclo de vida de la actividad y se analiza el código que activa la interfaz de usuario de la aplicación Phoneword.

Clase de la actividad

La aplicación Phoneword tiene una sola pantalla (actividad). La clase que activa la pantalla se denomina MainActivity y se encuentra en el archivo MainActivity.cs. El nombre MainActivity no tiene especial importancia en Android: aunque la convención es que el nombre de la primera actividad de una aplicación sea MainActivity, a Android no le importa si se le asigna otro nombre.

Al abrir MainActivity.cs, puede ver que la clase MainActivity es una subclase de la clase Activity y que la actividad está adornada con el atributo Activity:

[Activity (Label = "Phone Word", MainLauncher = true)]
public class MainActivity : Activity
{
  ...
}

El atributo Activity registra la actividad con el manifiesto de Android, lo que permite a Android saber que esta clase forma parte de la aplicación Phoneword administrada por este manifiesto. La propiedad Label establece el texto que se mostrará en la parte superior de la pantalla.

La propiedad MainLauncher le indica a Android que debe mostrar esta actividad cuando se inicia la aplicación. Esta propiedad cobra importancia a medida que se agregan más actividades (pantallas) a la aplicación, como se explica en la guía Hello, Android Multiscreen.

Ahora que ya hemos visto los aspectos básicos de MainActivity, vamos a profundizar en el código de la actividad. Para ello, introduciremos el ciclo de vida de la actividad.

Ciclo de vida de la actividad

En Android, las actividades pasan por distintas fases de un ciclo de vida en función de sus interacciones con el usuario. Las actividades se pueden crear, iniciar, pausar, reanudar, destruir, etc. La clase Activity contiene métodos que el sistema llama en determinados momentos del ciclo de vida de la pantalla. En el diagrama siguiente se ilustra la vida típica de una actividad, así como algunos de los métodos correspondientes del ciclo de vida:

Ciclo de vida de la actividad

Si invalida los métodos Activity del ciclo de vida, puede controlar cómo se carga la actividad, cómo reacciona al usuario e incluso qué sucede después de que desaparezca de la pantalla del dispositivo. Por ejemplo, puede invalidar los métodos del ciclo de vida del diagrama anterior para realizar algunas tareas importantes:

  • OnCreate: Crea vistas, inicializa las variables y realiza otras tareas de preparación que se deben realizar antes de que el usuario vea la actividad. Solo se llama una vez a este método cuando la actividad se carga en memoria.
  • OnResume: Realiza las tareas que se deben llevar a cabo cada vez que la actividad vuelve a la pantalla del dispositivo.
  • OnPause: Realiza las tareas que se deben llevar a cabo cada vez que la actividad sale de la pantalla del dispositivo.

Al agregar código personalizado a un método del ciclo de vida en Activityinvalida la implementación base de dicho método. Pulse el método del ciclo de vida existente (que ya tiene código asociado) y amplíe dicho método con su propio código. Llame a la implementación base desde dentro del método para asegurarse de que el código original se ejecuta antes que el código nuevo. En la sección siguiente se muestra un ejemplo.

El ciclo de vida de la actividad es una parte importante y compleja de Android. Si quiere obtener más información sobre las actividades cuando finalice la serie de introducción, lea la guía Activity Lifecycle (Ciclo de vida de la actividad). En esta guía, el aspecto siguiente en el que nos centraremos es la primera fase del ciclo de vida de la actividad, OnCreate.

OnCreate

Android llama al método OnCreate de Activity cuando crea la actividad (antes de que se muestre la pantalla al usuario). Puede invalidar el método OnCreate del ciclo de vida para crear vistas y preparar la actividad para el usuario:

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

    // Set our view from the "main" layout resource
    SetContentView (Resource.Layout.Main);
    // Additional setup code will go here
}

En la aplicación Phoneword, lo primero que hay que hacer en OnCreate es cargar la interfaz de usuario creada en Android Designer. Para cargar la interfaz de usuario, llame a SetContentView y pásele el nombre del diseño de recursos para el archivo de diseño: Main.axml. El diseño se encuentra en Resource.Layout.Main:

SetContentView (Resource.Layout.Main);

Cuando MainActivity se inicia, crea una vista que se basa en el contenido del archivo Main.axml. Tenga en cuenta que el nombre del archivo de diseño se hace coincidir con el nombre de la actividad (Main.axml es el diseño de MainActivity). Esto no es necesario desde el punto de vista de Android, pero a medida que agregue más pantallas a la aplicación, descubrirá que esta convención de nomenclatura permite que sea más fácil hacer coincidir el archivo de código con el archivo de diseño.

Después de preparar el archivo de diseño, puede empezar a buscar los controles. Para buscar un control, llame a FindViewById y pase el identificador de recurso del control:

EditText phoneNumberText = FindViewById<EditText>(Resource.Id.PhoneNumberText);
Button translateButton = FindViewById<Button>(Resource.Id.TranslateButton);
TextView translatedPhoneWord = FindViewById<TextView>(Resource.Id.TranslatedPhoneWord);

Ahora que tiene referencias a los controles en el archivo de diseño, puede empezar a programarlos para que respondan a la interacción del usuario.

Responder a la interacción del usuario

En Android, el evento Click escucha la entrada táctil del usuario. En esta aplicación, el evento Click se ha controlado con una expresión lambda, pero en su lugar se podría usar un delegado o un controlador de eventos con nombre. El código final de TranslateButton se parece a lo siguiente:

translateButton.Click += (sender, e) =>
{
    // Translate user’s alphanumeric phone number to numeric
    translatedNumber = PhonewordTranslator.ToNumber(phoneNumberText.Text);
    if (string.IsNullOrWhiteSpace(translatedNumber))
    {
        translatedPhoneWord.Text = string.Empty;
    }
    else
    {
        translatedPhoneWord.Text = translatedNumber;
    }
};

Pruebas, implementación y toques finales

Tanto Visual Studio para Mac como Visual Studio ofrecen numerosas opciones para probar e implementar una aplicación. En esta sección se incluyen las opciones de depuración, se muestra cómo probar las aplicaciones en un dispositivo y se presentan herramientas para crear iconos de aplicación personalizados para densidades de pantalla diferentes.

Herramientas de depuración

Los problemas relacionados con el código de la aplicación pueden ser difíciles de diagnosticar. Para ayudar a diagnosticar problemas de código complejo, puede establecer un punto de interrupciónexaminar el código o enviar información a la ventana de registro.

Implementar en un dispositivo

El emulador es un buen punto de partida para implementar y probar una aplicación, pero los usuarios no usarán la aplicación final en un emulador. Conviene probar las aplicaciones en un dispositivo real desde una fase inicial y con frecuencia.

Para que un dispositivo Android se pueda usar para probar aplicaciones, debe estar configurado para el desarrollo. En la guía Set Up Device for Development (Configurar el dispositivo para el desarrollo) se proporcionan instrucciones precisas sobre cómo preparar un dispositivo para el desarrollo.

Una vez que haya configurado el dispositivo, puede implementar en él. Para ello, conéctelo, pulse Inicio (Reproducir), selecciónelo en el cuadro de diálogo Seleccionar dispositivo y pulse Aceptar:

Seleccionar dispositivo de depuración

De este modo se inicia la aplicación en el dispositivo:

Escribir Phoneword

Establecer iconos para densidades de pantalla diferentes

Los dispositivos Android tienen tamaños de pantalla y resoluciones diferentes, y no todas las imágenes se muestran correctamente en todas las pantallas. Por ejemplo, a continuación se muestra una captura de pantalla de un icono de baja densidad en un Nexus 5 de alta densidad. Observe lo borroso que se ve en comparación con los iconos que lo rodean:

Icono borroso

Para resolverlo, se recomienda agregar iconos de distintas resoluciones en la carpeta Recursos. Android proporciona versiones diferentes de la carpeta mipmap para gestionar los iconos de los iniciadores de densidades diferentes: mdpi para pantallas de densidad media, hdpi para pantallas de alta densidad y xhdpixxhdpi y xxxhdpi para pantallas de muy alta densidad. Los iconos de tamaños diferentes se almacenan en las carpetas mipmap- correspondientes:

Carpetas mipmap

Android seleccionará el icono de la densidad adecuada:

Iconos con la densidad adecuada

Generar iconos personalizados

No todos tienen a su disposición un diseñador para crear los iconos e imágenes de inicio personalizados que una aplicación necesita para destacar. A continuación se indican varios enfoques alternativos para generar material gráfico personalizado para la aplicación:

  • Android Asset Studio: Se trata de un generador dentro del explorador y basado en web para todo tipo de iconos de Android, con vínculos a otras herramientas útiles de la comunidad. Funciona mejor en Google Chrome.
  • Sketch 3: Sketch es una aplicación de Mac para diseñar interfaces de usuario, iconos y mucho más. Es la aplicación que se usó para diseñar el conjunto de iconos de aplicación e imágenes de inicio de Xamarin. Sketch 3 está disponible en App Store y cuesta aproximadamente 80 $. También puede probar la versión gratuita Sketch Tool.
  • Pixelmator: Una aplicación versátil de edición de imágenes para Mac que cuesta aproximadamente 30 $.
  • Glyphish: Conjuntos de iconos prediseñados de alta calidad que se pueden comprar o descargar de forma gratuita.
  • Fiverr: Elija entre diversos diseñadores para que creen para usted un conjunto de iconos a partir de 5 $. Probablemente elegirá un diseñador al azar, pero se trata de un buen recurso si necesita que le diseñen iconos sobre la marcha.

Para obtener más información sobre los tamaños de icono y los requisitos, consulte la guía Android Resources (Recursos de Android).

Agregar paquetes de Google Play Services

Google Play Services es un conjunto de bibliotecas de complementos que permite a los desarrolladores de Android aprovechar las características más recientes de Google, como Google Maps, Google Cloud Messaging e In-App Billing. Antes, Xamarin proporcionaba enlaces a todas las bibliotecas de Google Play Services en forma de un único paquete, pero a partir de Visual Studio para Mac, hay un nuevo cuadro de diálogo de proyecto para seleccionar los paquetes de Google Play Services que se incluyen en la aplicación.

Para agregar una o más bibliotecas de Google Play Services, haga clic con el botón derecho en el nodo Paquetes del árbol del proyecto y haga clic en Add Google Play Services… (Agregar Google Play Services…):

Agregar Google Play Services

Cuando aparezca el cuadro de diálogo Add Google Play Services… (Agregar Google Play Services…), seleccione los paquetes (NuGet) que quiere agregar al proyecto:

Seleccionar paquetes

Al seleccionar un servicio y hacer clic en Agregar paquete, Visual Studio para Mac descarga e instala el paquete que seleccione, así como los paquetes dependientes de Google Play Services que requiere. En algunos casos, podría ver un cuadro de diálogo de Aceptación de la licencia que le solicita que haga clic en Aceptar para que se instalen los paquetes:

Aceptación de licencia

Resumen

¡Enhorabuena! Ahora ya debería conocer bien los componentes de una aplicación de Xamarin.Android, así como las herramientas necesarias para crearla.

En el siguiente tutorial de la serie de introducción, podrá ampliar la aplicación para que controle varias pantallas a medida que explora la arquitectura y conceptos más avanzados de Android.

WorkShop lab1 para windows

En este tutorial, creará una aplicación que convierte un número de teléfono alfanumérico (escrito por el usuario) en un número de teléfono numérico y muestra ese número al usuario. La aplicación final tiene este aspecto:

Captura de pantalla de la aplicación una vez completada

Requisitos

Para seguir este tutorial, necesitará lo siguiente:

  • Windows 7 o posterior.
  • Visual Studio 2015 Professional o posterior.

En este tutorial se presupone que está instalada la última versión de Xamarin.Android y que se está ejecutando en la plataforma que ha seleccionado. Para obtener una guía de instalación de Xamarin.Android, vea las guías Instalación de Xamarin.Android. Antes de empezar, descargue y descomprima el conjunto Iconos de aplicación y pantallas de inicio de Xamarin.

Configuración de los emuladores

Si está usando el emulador Android SDK de Google, le recomendamos que configure el emulador para usar la aceleración de hardware. Las instrucciones para configurar la aceleración de hardware están disponibles en Aceleración de hardware.

Si está usando el emulador de Android de Visual Studio, Hyper-V debe estar habilitado en su equipo. Para obtener más información sobre la configuración del emulador de Android de Visual Studio, vea Requisitos de sistema del emulador de Visual Studio para Android.

Tutorial

  1. Inicie Visual Studio. Para crear un proyecto, haga clic en Archivo > Nuevo > Proyecto.
  2. En el cuadro de diálogo Nuevo proyecto, haga clic en la plantilla Aplicación vacía (Android). Asigne al nuevo proyecto el nombre de Phoneword. Haga clic en Aceptar para crear el nuevo proyecto:

    El nuevo proyecto es Phoneword

  3. Después de que el nuevo proyecto se haya creado, expanda la carpeta Recursos y, después, la carpeta Diseño en el Explorador de soluciones. Haga doble clic en Main.axml para abrirlo en Android Designer. Este es el archivo de diseño para la pantalla de la aplicación:

    Abrir Main.axml

  4. En el Cuadro de herramientas (el área de la izquierda), escriba text en el campo de búsqueda y arrastre un widget de Texto (grande) a la superficie de diseño (el área del centro):

    Agregar un widget de texto grande

  5. Con el control de Texto (grande) seleccionado en la superficie de diseño, use el panel Propiedades para cambiar la propiedad text del widget de Texto (grande) a Enter a Phoneword: como se muestra aquí:

    Establecer las propiedades de texto grande

  6. Arrastre un widget de Texto sin formato del Cuadro de herramientas a la superficie de diseño y colóquelo debajo del widget de Texto (grande):

    Agregar un widget de texto sin formato

  7. Con el widget de Texto sin formato seleccionado en la superficie de diseño, use el panel Propiedades para cambiar la propiedad id del widget de Texto sin formato a @+id/PhoneNumberText y cambiar la propiedad text a 1-855-XAMARIN:

    Establecer las propiedades de texto sin formato

  8. Arrastre un Botón del Cuadro de herramientas a la superficie de diseño y colóquelo debajo del widget de Texto sin formato:

    Arrastrar el botón Traducir al diseño

  9. Con el botón seleccionado en la superficie de diseño, use el panel Propiedades para cambiar la propiedad id del botón a @+id/TranslateButton y cambiar la propiedad text a Translate:

    Establecer las propiedades del botón Traducir

  10. Arrastre la vista de texto desde Cuadro de herramientas hasta la superficie de diseño y colóquela debajo del widget Botón. Establezca la propiedad id de la vista de texto en @+id/TranslatedPhoneWord y cambie el text por una cadena vacía:

    Establecer las propiedades en la vista de texto.

  11. Guarde su trabajo presionando CTRL+S.
  12. El siguiente paso consiste en agregar código para convertir números de teléfono de formato alfanumérico a numérico. Agregue un nuevo archivo al proyecto haciendo clic con el botón derecho en el proyecto Phoneword en el panel del Explorador de soluciones y seleccionando Agregar > Nuevo elemento…, como se muestra a continuación:

    Agregar nuevo elemento

  13. En el cuadro de diálogo Agregar nuevo elemento, seleccione Visual C# > Código y asigne al nuevo archivo de código el nombre PhoneTranslator.cs:

    Agregar PhoneTranslator.cs

  14. Esto crea una nueva clase de C# vacía. Inserte el código siguiente en este archivo:
    using System.Text;
    using System;
    namespace Core
    {
        public static class PhonewordTranslator
        {
            public static string ToNumber(string raw)
            {
                if (string.IsNullOrWhiteSpace(raw))
                    return "";
                else
                    raw = raw.ToUpperInvariant();
    
                var newNumber = new StringBuilder();
                foreach (var c in raw)
                {
                    if (" -0123456789".Contains(c))
                    {
                        newNumber.Append(c);
                    }
                    else 
                    {
                        var result = TranslateToNumber(c);
                        if (result != null)
                            newNumber.Append(result);
                    }
                    // otherwise we've skipped a non-numeric char
                }
                return newNumber.ToString();
            }
            static bool Contains (this string keyString, char c)
            {
                return keyString.IndexOf(c) >= 0;
            }
            static int? TranslateToNumber(char c)
            {
                if ("ABC".Contains(c))
                    return 2;
                else if ("DEF".Contains(c))
                    return 3;
                else if ("GHI".Contains(c))
                    return 4;
                else if ("JKL".Contains(c))
                    return 5;
                else if ("MNO".Contains(c))
                    return 6;
                else if ("PQRS".Contains(c))
                    return 7;
                else if ("TUV".Contains(c))
                    return 8;
                else if ("WXYZ".Contains(c))
                    return 9;
                return null;
            }
        }
    }

    Guarde los cambios en el archivo PhoneTranslator.cs haciendo clic en Archivo > Guardar (o presionando CTRL+S) y, después, cierre el archivo.

  15. El siguiente paso consiste en agregar código para conectar la interfaz de usuario al insertar código auxiliar en la clase MainActivity. Empiece con la conexión del botón Traducir. En la clase MainActivity, busque el método OnCreate. El siguiente paso consiste en agregar el código de botón dentro de OnCreate, debajo de las llamadas base.OnCreate(bundle) y SetContentView (Resource.Layout.Main). En primer lugar, modifique el código de plantilla para que el método OnCreate sea similar al siguiente:
    using System;
    using Android.App;
    using Android.Content;
    using Android.Widget;
    using Android.OS;
    
    namespace Phoneword
    {
        [Activity (Label = "Phone Word", MainLauncher = true)]
        public class MainActivity : Activity
        {
            protected override void OnCreate (Bundle bundle)
            {
                base.OnCreate (bundle);
    
                // Set our view from the "main" layout resource
                SetContentView (Resource.Layout.Main);
    
                // New code will go here
            }
        }
    }
  16. Obtenga una referencia de los controles que se han creado en el archivo de diseño con Android Designer. Agregue el código siguiente dentro del método OnCreate, después de la llamada a SetContentView:
    // Get our UI controls from the loaded layout
    EditText phoneNumberText = FindViewById<EditText>(Resource.Id.PhoneNumberText);
    TextView translatedPhoneWord = FindViewById<TextView>(Resource.Id.TranslatedPhoneWord);
    Button translateButton = FindViewById<Button>(Resource.Id.TranslateButton);
  17. Agregue el código que responda a las pulsaciones del usuario del botón Traducir. Agregue el siguiente código al método OnCreate (después de las líneas que se han agregado en el paso anterior):
    // Add code to translate number
    string translatedNumber = string.Empty;
    
    translateButton.Click += (sender, e) =>
    {
        // Translate user’s alphanumeric phone number to numeric
        translatedNumber = PhonewordTranslator.ToNumber(phoneNumberText.Text);
        if (string.IsNullOrWhiteSpace(translatedNumber))
        {
            translatedPhoneWord.Text = string.Empty;
        }
        else
        {
            translatedPhoneWord.Text = translatedNumber;
        }
    };
  18. Guarde su trabajo seleccionando Archivo > Guardar todo (o presionando CTRL-MAYÚS-S) y compile la aplicación seleccionando Compilar > Recompilar solución (o presionando CTRL-MAYÚS-B).

    Si hay errores, repase los pasos anteriores y corrija cualquier error hasta que la aplicación se compile correctamente. Si obtiene un error de compilación como El recurso no existe en el contexto actual, compruebe que el nombre del espacio de nombres en MainActivity.cs coincida con el nombre del proyecto (Phoneword) y, después, recompile completamente la solución. Si sigue obteniendo errores de compilación, compruebe que ha instalado las últimas actualizaciones de Xamarin.Android.

  19. Ahora debe tener una aplicación que funciona –es el momento de agregar los toques finales. En MainActivity.cs, edite el Label para el MainActivityLabel es lo que Android muestra en la parte superior de la pantalla para que los usuarios conozcan el lugar en el que se encuentran en la aplicación. En la parte superior de la clase MainActivity, cambie Label por Phone Word como se muestra aquí:
    namespace Phoneword
    {
        [Activity (Label = "Phone Word", MainLauncher = true)]
        public class MainActivity : Activity
        {
            ...
        }
    }
  20. Ahora es el momento de establecer el icono de la aplicación. De forma predeterminada, Visual Studio proporcionará un icono predeterminado para el proyecto. Vamos a eliminar estos archivos de la solución y reemplazarlos por un icono diferente. Expanda la carpeta Recursos en Panel de solución. Observe que hay cinco carpetas que tienen el prefijo mipmap- y que cada una de estas carpetas contiene un archivo Icon.png:

    carpetas mipmap- y archivos Icon.png

    Es necesario eliminar del proyecto todos estos archivos de icono. Haga clic con el botón derecho en cada uno de los archivos Icon.png y haga clic en Eliminar en el menú contextual:

    Eliminar archivo Icon.png predeterminado

    Haga clic en el botón Eliminar en el cuadro de diálogo.

  21. Luego, descargue y descomprima el conjunto de iconos de aplicación de Xamarin. Este archivo ZIP contiene los iconos de la aplicación. Todos los iconos son idénticos visualmente, pero se representan correctamente con resoluciones diferentes en distintos dispositivos con distintas densidades de pantalla. El conjunto de archivos debe copiarse en el proyecto Xamarin.Android. En Visual Studio, en el Explorador de soluciones, haga clic con el botón derecho en la carpeta mipmap-hdpi y seleccione Agregar > Elementos existentes:

    Agregar archivos

  22. En el cuadro de diálogo de selección, vaya al directorio descomprimido de los iconos de aplicación de Xamarin y abra la carpeta mipmap-hdpi. Seleccione Icon.png y haga clic en Agregar.
  23. Repita estos pasos para cada una de las carpetas mipmap- hasta que el contenido de las carpetas de iconos de aplicación de Xamarin mipmap- se copie en las carpetas mipmap- equivalentes en el proyecto Phoneword.
  24. Después de copiar todos los iconos en el proyecto de Xamarin.Android, abra el cuadro de diálogo Opciones del proyecto haciendo clic con el botón derecho en el proyecto en Panel de solución. Haga clic en Compilar > Aplicación de Android y seleccione @mipmap/icon en el cuadro combinado Icono de aplicación:

    Establecer el icono del proyecto

  25. Por último, pruebe la aplicación ejecutándola en un dispositivo o emulador Android y traduciendo un Phoneword:

    Captura de pantalla de la aplicación una vez completada

WorkShop lab1 para mac

Esta guía se divide en dos partes que ayudaran a compilar nuestro workshop, aplicación de Xamarin.Android (mediante Visual Studio o Visual Studio para Mac) y a comprender los aspectos básicos del desarrollo de aplicaciones de Android con Xamarin.

Basado en: Hello Xamarin developer.xamarin.com/es-es

Android APP

En este tutorial, crearemos una aplicación que convierte un número de teléfono alfanumérico (escrito por el usuario) en un número de teléfono numérico y muestra ese número al usuario. La aplicación final tiene este aspecto:

Captura de pantalla de la aplicación una vez completada

Requisitos

Para seguir este tutorial, necesitará lo siguiente:

  • La versión más reciente de Visual Studio para Mac.

En este tutorial se presupone que está instalada la última versión de Xamarin.Android y que se está ejecutando en la plataforma que ha seleccionado. Para obtener una guía de instalación de Xamarin.Android, vea las guías Instalación de Xamarin.Android. Antes de empezar, descargue y descomprima el conjunto Iconos de aplicación y pantallas de inicio de Xamarin.

Configuración de los emuladores

Si estás usando el emulador Android SDK de Google, le recomendamos que configure el emulador para usar la aceleración de hardware. Las instrucciones para configurar la aceleración de hardware están disponibles en Aceleración de hardware.

Vamos con el workshop

  1. Inicie Visual Studio para Mac desde la carpeta Aplicaciones o desde Spotlight. (cmd más espacio)
  2. Haga clic en Nueva solución… para crear un proyecto.
  3. En el cuadro de diálogo Choose a template for your new project (Elegir una plantilla para el nuevo proyecto), haga clic en Android > Aplicación y seleccione la plantilla Aplicación de Android. Haga clic en Siguiente.

    Elegir la plantilla Aplicación de Android

  4. En el cuadro de diálogo Configure su aplicación de Android, asigne a la nueva aplicación el nombre Phoneword y haga clic en Siguiente.

    Configurar la aplicación de Android

    En el cuadro de diálogo Configure su aplicación de Android, deje los nombres de solución y proyecto establecidos en Phoneword y haga clic en Crear para crear el proyecto.

  5. Después de que el nuevo proyecto se haya creado, expanda la carpeta Recursos y, después, la carpeta Diseño en el panel de Solución. Haga doble clic en Main.axml para abrirlo en Android Designer. Este es el archivo de diseño de la pantalla cuando se visualiza en Android Designer:

    Abrir Main.axml

  6. Seleccione el botón Hello World, Click Me! (Hola a todos, haz clic aquí)Botón en la superficie de diseño; pulse la tecla Eliminar para quitarlo.
  7. Desde el Cuadro de herramientas (el área de la derecha), escriba text en el campo de búsqueda y arrastre un widget de Texto (grande) a la superficie de diseño (el área del centro):

    Agregar un widget de texto grande

  8. Con el widget de Texto (grande) seleccionado en la superficie de diseño, puede usar el panel Propiedades para cambiar la propiedad Text del widget de Texto (grande) a Enter a Phoneword: como se muestra a continuación:

    Establecer las propiedades del widget de texto grande

  9. Después, arrastre un widget de Texto sin formato del Cuadro de herramientas a la superficie de diseño y colóquelo debajo del widget de Texto (grande). Tenga en cuenta que puede usar el campo de búsqueda para ayudarle a buscar widgets por el nombre:

    Agregar un widget de texto sin formato

  10. Con el widget de Texto sin formato seleccionado en la superficie de diseño, puede usar el panel Propiedades para cambiar la propiedad Id del widget de Texto sin formato a @+id/PhoneNumberText y cambiar la propiedad Text a 1-855-XAMARIN:

    Establecer las propiedades del widget de texto sin formato

  11. Arrastre un Botón del Cuadro de herramientas a la superficie de diseño y colóquelo debajo del widget de Texto sin formato:

    Agregar un botón

  12. Con el Botón seleccionado en la superficie de diseño, puede usar el panel Propiedades para cambiar la propiedad Iddel Botón a @+id/TranslateButton y cambiar la propiedad Text a Translate:

    Configurar como el botón Traducir

  13. Arrastre la vista de texto desde Cuadro de herramientas hasta la superficie de diseño y colóquela debajo del widget Botón. Con la vista de texto seleccionada, establezca la propiedad id de la vista de texto en @+id/TranslatedPhoneWord y cambie el text por una cadena vacía:

    Establecer las propiedades en la vista de texto.

  14. Guarde su trabajo presionando ⌘ + S.
  15. Ahora, agregue código para convertir números de teléfono de formato alfanumérico a numérico. Agregue un nuevo archivo al proyecto haciendo clic en el icono de engranaje junto al proyecto Phoneword en el panel de Solución y seleccionando Agregar > Nuevo archivo…:

    Agregar un nuevo archivo al proyecto

  16. En el cuadro de diálogo Nuevo archivo, haga clic en General > Clase vacía, asigne al archivo nuevo el nombre PhoneTranslator y haga clic en Nuevo. Esto crea una nueva clase de C# vacía.
  17. Quite todo el código de plantilla de la clase nueva y reemplácelo por el siguiente código:
    using System.Text;
    using System;
    namespace Core
    {
        public static class PhonewordTranslator
        {
            public static string ToNumber(string raw)
            {
                if (string.IsNullOrWhiteSpace(raw))
                    return "";
                else
                    raw = raw.ToUpperInvariant();
    
                var newNumber = new StringBuilder();
                foreach (var c in raw)
                {
                    if (" -0123456789".Contains(c))
                    {
                        newNumber.Append(c);
                    }
                    else 
                    {
                        var result = TranslateToNumber(c);
                        if (result != null)
                            newNumber.Append(result);
                    }
                    // otherwise we've skipped a non-numeric char
                }
                return newNumber.ToString();
            }
            static bool Contains (this string keyString, char c)
            {
                return keyString.IndexOf(c) >= 0;
            }
            static int? TranslateToNumber(char c)
            {
                if ("ABC".Contains(c))
                    return 2;
                else if ("DEF".Contains(c))
                    return 3;
                else if ("GHI".Contains(c))
                    return 4;
                else if ("JKL".Contains(c))
                    return 5;
                else if ("MNO".Contains(c))
                    return 6;
                else if ("PQRS".Contains(c))
                    return 7;
                else if ("TUV".Contains(c))
                    return 8;
                else if ("WXYZ".Contains(c))
                    return 9;
                return null;
            }
        }
    }

    Guarde los cambios en PhoneTranslator.cs pulsando Archivo > Guardar (o presionando ⌘ + S) y cierre el archivo. Asegúrese de que no hay errores de tiempo de compilación al volver a compilar la solución.

  18. El siguiente paso consiste en agregar código para conectar la interfaz de usuario al agregar código auxiliar en la clase MainActivity. Haga doble clic en el archivo MainActivity.cs en Panel de solución para abrirlo.
  19. Para empezar, agregue un controlador de eventos al botón Traducir. En la clase MainActivity, busque el método OnCreate. Agregue el código de botón dentro de OnCreate, debajo de las llamadas a base.OnCreate(bundle) y SetContentView (Resource.Layout.Main). Quite el código de control del botón de plantilla de manera que el método OnCreate tenga el aspecto siguiente:
    using System;
    using Android.App;
    using Android.Content;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using Android.OS;
    
    namespace Phoneword
    {
        [Activity (Label = "Phone Word", MainLauncher = true)]
        public class MainActivity : Activity
        {
            protected override void OnCreate (Bundle bundle)
            {
                base.OnCreate (bundle);
    
                // Set our view from the "main" layout resource
                SetContentView (Resource.Layout.Main);
    
                // Our code will go here
            }
        }
    }
  20. Después, se necesita una referencia de los controles que se han creado en el archivo de diseño con Android Designer. Agregue el código siguiente dentro del método OnCreate (después de la llamada a SetContentView):
    // Get our UI controls from the loaded layout
    EditText phoneNumberText = FindViewById<EditText>(Resource.Id.PhoneNumberText);
    TextView translatedPhoneWord = FindViewById<TextView>(Resource.Id.TranslatedPhoneWord);
    Button translateButton = FindViewById<Button>(Resource.Id.TranslateButton);
  21. Agregue el código que responda a las pulsaciones del usuario del botón Traducir agregando el siguiente código al método OnCreate (después de las líneas que se han agregado en el último paso):
    // Disable the "Call" button
    callButton.Enabled = false;
    
    // Add code to translate number
    string translatedNumber = string.Empty;
    
    translateButton.Click += (sender, e) =>
    {
        // Translate user’s alphanumeric phone number to numeric
        translatedNumber = PhonewordTranslator.ToNumber(phoneNumberText.Text);
        if (string.IsNullOrWhiteSpace(translatedNumber))
        {
            translatedPhoneWord.Text = string.Empty;
        }
        else
        {
            translatedPhoneWord.Text = translatedNumber;
        }
    };
  22. Guarde el trabajo y compile la aplicación seleccionando Compilar > Compilar todo (o presionando ⌘ + B). Si la aplicación se compila, obtendrá un mensaje de operación correcta en la parte superior de Visual Studio para Mac:

    Si hay errores, repase los pasos anteriores y corrija cualquier error hasta que la aplicación se compile correctamente. Si obtiene un error de compilación como El recurso no existe en el contexto actual, compruebe que el nombre del espacio de nombres en MainActivity.cs coincida con el nombre del proyecto (Phoneword) y, después, recompile completamente la solución. Si sigue obteniendo errores de compilación, compruebe que ha instalado las últimas actualizaciones de Xamarin.Android y Xamarin Studio.

  23. Ahora que tiene una aplicación que funciona, es el momento de agregar los toques finales. Empiece editando Labelpara MainActivityLabel es lo que Android muestra en la parte superior de la pantalla para que los usuarios conozcan el lugar en el que se encuentran en la aplicación. En la parte superior de la clase MainActivity, cambie Label por Phone Word como se muestra aquí:
    namespace Phoneword
    {
        [Activity (Label = "Phone Word", MainLauncher = true)]
        public class MainActivity : Activity
        {
            ...
        }
    }
  24. Ahora es el momento de establecer el icono de la aplicación. De forma predeterminada, Visual Studio para Mac proporcionará un icono predeterminado para el proyecto. Vamos a eliminar estos archivos de la solución y reemplazarlos por un icono diferente. Expanda la carpeta Recursos en Panel de solución. Observe que hay cinco carpetas que tienen el prefijo mipmap- y que cada una de estas carpetas contiene un archivo Icon.png:

    carpetas mipmap- y archivos Icon.png

    Es necesario eliminar del proyecto todos estos archivos de icono. Haga clic con el botón derecho en cada uno de los archivos Icon.png y haga clic en Quitar en el menú contextual:

    Eliminar archivo Icon.png predeterminado

    Haga clic en el botón Eliminar en el cuadro de diálogo.

  25. Luego, descargue y descomprima el conjunto de iconos de aplicación de Xamarin. Este archivo ZIP contiene los iconos de la aplicación. Todos los iconos son idénticos visualmente, pero se representan correctamente con resoluciones diferentes en distintos dispositivos con distintas densidades de pantalla. El conjunto de archivos debe copiarse en el proyecto Xamarin.Android. En Visual Studio para Mac, en Panel de solución, haga clic con el botón derecho en la carpeta mipmap-hdpi y seleccione Agregar > Agregar archivos:

    Agregar archivos

  26. En el cuadro de diálogo de selección, vaya al directorio descomprimido de los iconos de aplicación de Xamarin y abra la carpeta mipmap-hdpi. Seleccione Icon.png y haga clic en Abrir.
  27. En el cuadro de diálogo Add File to Folder (Agregar archivo a carpeta), seleccione Copy the file into the directory (Copiar el archivo en el directorio) y haga clic en Aceptar:

    Cuadro de diálogo Copiar el archivo en el directorio

  28. Repita estos pasos para cada una de las carpetas mipmap- hasta que el contenido de las carpetas de iconos de aplicación de Xamarin mipmap- se copie en las carpetas mipmap- equivalentes en el proyecto Phoneword.
  29. Después de copiar todos los iconos en el proyecto de Xamarin.Android, abra el cuadro de diálogo Opciones del proyecto haciendo clic con el botón derecho en el proyecto en Panel de solución. Haga clic en Compilar > Aplicación de Android y seleccione @mipmap/icon en el cuadro combinado Icono de aplicación:

    Establecer el icono del proyecto

  30. Por último, pruebe la aplicación ejecutándola en un dispositivo o emulador Android y traduciendo un Phoneword:

    Captura de pantalla de la aplicación una vez completada

Ha completado su primera aplicación de Xamarin.Android. Ahora es el momento de analizar las herramientas y los conocimientos que ha aprendido.

Seguimos con la ppt de Análisis detallado

 

Xamarin Test Cloud que es

Los usuarios móviles están quizás entre los consumidores más exigentes de software hoy en día, y esperan que las aplicaciones móviles sean sensibles, libres de errores y de bajo costo. Las aplicaciones que no cumplan con esta expectativa se desinstalarán rápidamente y se le asignará una calificación muy baja.

La forma más efectiva de validar el comportamiento de una aplicación es ejecutándola y usándola. Si se comporta como se esperaba, sin fallar o devolver resultados incorrectos, entonces la aplicación está en buena forma y puede ser liberada a los usuarios sin preocuparse de que causará frustración o será inutilizable. Este proceso, de probar la interfaz de usuario mediante el uso de una aplicación y la interacción con ella, se conoce como prueba de aceptación de la interfaz de usuario.

Tradicionalmente, sin embargo, la aceptación de interfaz de usuario ha sido extremadamente caro debido a su naturaleza manual. Históricamente ha requerido mucha mano de obra para desplegar la aplicación y luego usarla, verificando que se comporta correctamente. Multiplicar que por cada construcción que necesita pruebas, así como cada dispositivo y sistema operativo en el que se necesita la prueba, y el costo puede dispararse exponencialmente, lo que significa que las pruebas de aceptación de la interfaz de usuario ha estado fuera del alcance de casi todas las organizaciones, .

Xamarin Test Cloud es una solución basada en la nube que proporciona herramientas que admiten pruebas automatizadas de aceptación de la interfaz de usuario de aplicaciones móviles a través de cientos de dispositivos diferentes. Esto permite a cualquier persona asegurarse de que su aplicación se realiza correctamente y eficientemente a través de una variedad de dispositivos con el mínimo esfuerzo. Además, debido a que se basa en la nube, los esfuerzos de mantenimiento y adquisición se eliminan del consumidor de prueba, que puede centrarse en comprobar que la aplicación funciona correctamente.

El ecosistema Xamarin Test Cloud consta de las siguientes partes:

  • Xamarin.UITest – Este es un marco que permite que las pruebas se escriban en C # utilizando la popular biblioteca de pruebas de NUnit. Este marco es adecuado para los equipos que ya están capacitados para escribir pruebas NUnit y / o desarrollar sus aplicaciones móviles con Xamarin.
  • Test Cloud – Test Cloud es un servicio basado en la nube que consiste en miles de dispositivos móviles físicos. Los usuarios suben sus aplicacionesy pruebas a Test Cloud, que instalará las aplicaciones en los dispositivos y ejecutará las pruebas. Cuando se completan las pruebas, Test Cloud, los resultados se ponen a disposición de los usuarios a través de un fácil de usar e informativo basado en front-end para web.

 

  • Xamarin Test Recorder – Esta herramienta, todavía en desarrollo, puede simplificar la creación de pruebas y es ideal para alguien que es nuevo en Xamarin.UITest y no está familiarizado con las API. Los probadores pueden iniciar Test Recorder, conectarlo al dispositivo, simulador o emulador, y luego empezar a usar la aplicación para móviles. Test Recorder capturará las interacciones entre el usuario y la aplicación móvil y emitirá un Xamarin.UITest en C # para ese escenario.

El sistema Xamarin Test Cloud proporciona las bibliotecas y herramientas que permiten a los equipos crear pruebas automatizadas, ejecutarlas en una multitud de dispositivos y validar que el comportamiento es correcto. La aplicación móvil y las pruebas se suben a Xamarin Test Cloud, que instalará la aplicación y ejecutará las pruebas en cientos de dispositivos físicos. Esto se conoce como una prueba de ejecución . Cuando se complete la prueba, Test Cloud enviará una notificación con los resultados de la prueba. Este flujo de trabajo se puede ver en el siguiente diagrama:

La ejecución de prueba puede realizarse manualmente por un usuario o como parte de un flujo de trabajo de Integración continua (CI) que envía automáticamente nuevas compilaciones de aplicaciones a Xamarin Test Cloud cuando se comprueban los cambios de código:

 

La anatomía del marco de la nube de la prueba

Las interacciones automatizadas con una aplicación móvil requieren algún tipo de biblioteca de automatización que simule la acción de un usuario y permita que la prueba compruebe el estado de la interfaz de usuario para probar que la aplicación funciona correctamente. Tanto Android como iOS tienen sus propios marcos de automatización de UI propietarios. Estos dos conjuntos muy diferentes de API de prueba resultarían desafiantes para un probador que quiere escribir pruebas de plataforma cruzada. Para ayudar a resolver la preocupación, se instalarán uno o dos componentes auxiliares en el dispositivo móvil junto con la aplicación:

  • Xamarin Test Cloud Agent – Este es un servidor HTTP ligero que interactúa con las pruebas a través de JSON a través de HTTP. El Xamarin Test Cloud Agent es un intermediario que tomará las consultas (y en algunos casos, acciones) de las pruebas y las realizará en la aplicación que está siendo probada. El Xamarin Test Cloud Agent es necesario para las aplicaciones de Android y iOS, y tiene un papel ligeramente diferente en cada plataforma.

 

  • DeviceAgent – Se instala sólo las aplicaciones iOS que se construyen con Xcode 8. Lógicamente es muy similar a t Xamarin Test Cloud Agent – es responsable de realizar gestos y consultas avanzadas en las vistas de iOS, pero lo hace utilizando un conjunto diferente de API de prueba.

Xamarin Test Cloud Agent en Android

En Android, el Agente de Cloud Test de Xamarin es responsable de usar las API de automatización de Android para controlar la interfaz de usuario y localizar las vistas para que una prueba pueda interactuar con ellas. Se incluye en un APK separado y se ejecuta como una aplicación independiente, que tiene permiso para automatizar la aplicación bajo prueba. Esto es posible, porque cuando la prueba se implementa en el dispositivo móvil, UITest firmarán ambos paquetes de aplicaciones con la misma clave.

Xamarin Test Cloud Agent en iOS

Cloud Agent de prueba tiene un papel ligeramente diferente en las aplicaciones de iOS; por sí mismo, no automatiza la aplicación que se está probando. En su lugar, el Agente de la nube de prueba interrogará la ventana activa y recuperará información sobre las vistas para el usuario. La información de vista se devuelve al script de prueba. A continuación, el script de prueba automatizará la aplicación iOS con la ayuda de otro componente denominado DeviceAgent . El DeviceAgent simulará los gestos y las acciones para la prueba (usando la API de automatización proveer con Xcode 8) y si es necesario devolver el resultado de esas interacciones a la prueba:

El agente Xamarin Test Cloud está disponible a través de un paquete NuGet y debe incluirse en el paquete de aplicaciones antes de que se pueda ejecutar una prueba. El agente Xamarin Test Cloud sólo debe incluirse en las compilaciones de depuración de la aplicación. Apple rechazará las aplicaciones que se envíen con el Agente de Cloud de Prueba de Xamarin vinculado al Paquete de aplicaciones.

Las versiones más recientes de Calabash y UITest soportan pruebas con Xcode 7 y Xcode 8. El verison de Xcode usado para construir la aplicación determinará qué API de automatización nativa se usa para automatizar la aplicación. El Marco de pruebas y compatibilidad con iOS para Calabash está determinado por la versión de Xcode que se utiliza. Vea la tabla abajo:

VERSIÓN DE IOS LOCAL CON XCODE 7 LOCAL CON XCODE 8
iOS7 UIAutomation n / A
IOS 8 UIAutomation n / A
IOS 9 UIAutomation DeviceAgent
IOS 10 n / A DeviceAgent

Por ejemplo, un Mac con Xcode 8 instalado podrá probar en dispositivos que ejecutan iOS 10 o iOS 9 usando DeviceAgent, pero no podría probar en iOS 8 o inferior.

El paquete NuGet de Agente de la nube de prueba de Xamarin es solo para aplicaciones Xamarin.iOS; No está disponible (o requerido) para las aplicaciones de Xamarin.Android.

Ejecución de pruebas en Xamarin Test Cloud

Ejecución de pruebas en Xamarin Test Cloud es conceptualmente similar a ejecutar pruebas localmente, excepto que Xamarin Test Cloud alberga las pruebas y las ejecutará en dispositivos seleccionados:

Para facilitar esto, las pruebas se cargan junto con la aplicación cuando se envía a Xamarin Test Cloud para pruebas. Xamarin Test Cloud reiniciará el dispositivo en un estado limpio, instalará la aplicación y ejecutará las pruebas.

Limitaciones

Las pruebas que se envían a Xamarin Test Cloud se añaden a una cola y se ejecutarán cuando los dispositivos estén disponibles. Una vez que ha comenzado una prueba, están sujetos a las siguientes limitaciones de tiempo en un dispositivo:

  • Las pruebas para una suscripción pagada se limitan a 360 minutos.
  • Las pruebas de una cuenta de prueba están limitadas a 90 minutos.
  • Las pruebas para una cuenta de la Universidad Xamarin están limitadas a 30 minutos.
  • Los Xamarin.UITests individuales no pueden exceder de 30 minutos cada uno.
  • Los pasos de Calabash individuales no pueden exceder de 10 minutos cada uno.
  • Las cuentas de la prueba y de la universidad se limitan a 10 funcionamientos de prueba por día.

ℹ Los tiempos anteriores no incluyen la espera de que un determinado dispositivo esté disponible, los dispositivos muy utilizados pueden requerir una larga espera.

No es posible realizar una prueba en Xamarin Test Cloud para realizar, simular / emular o controlar lo siguiente:

  • Regulación de la red
  • Inicio de la aplicación en la orientación específica del dispositivo
  • VPN en la red corporativa en lugar de abrir puertos al firewall
  • Integración con otras aplicaciones instaladas en el dispositivo

Xamarin Test Cloud no puede admitir las siguientes características de hardware:

  • Bluetooth
  • Aceleración WiFi
  • Cámara
  • Físicamente girando el dispositivo
  • Simulación de diferentes condiciones de la batería

Traducido al español de la documentación oficial

https://developer.xamarin.com/guides/testcloud/introduction-to-test-cloud/#The_Anatomy_of_the_Test_Cloud_Framework

Una aplicación de Azure IOT y Mobile de ejemplo

Hoy me puse depurar el proyecto MyDriving de Microsoft una serie de aplicaciones que demuestran el diseño e implementación de una solución completa de Internet de Cosas (IoT) que recopila la telemetría de los dispositivos, procesa esos datos en la nube y aplica el aprendizaje de la máquina para proporcionar una respuesta adaptativa. La demostración registra datos sobre viajes en automóvil utilizando tanto un teléfono móvil como un adaptador de Diagnóstico a bordo (OBD) que recopila información del sistema de control de su vehículo. El backend Azure utiliza estos datos para proporcionar retroalimentación sobre su estilo de conducción en comparación con otros usuarios.

Repositorio en

https://github.com/lawebdeprogramador/MyDriving

Trabajar con OAuth2 y OpenID desde una aplicación Xamarin utilizando IdentityServer3

OAuth2 es un protocolo abierto que permite la autorización segura en un método simple y estándar de aplicaciones web, móviles y de escritorio . OpenID Connect es una capa de identidad simple en la parte superior del protocolo OAuth2 .
En cierto modo, OAuth2 es un protocolo para construir,
Lo que es exactamente lo que hace OpenID Connect. OIDC es más estricto que el protocolo OAuth2, que, gracias a ese rigor, lo abre a otros escenarios, como la autenticación. En estos días, la mayoría de las aplicaciones utilizan OIDC en lugar de OAuth2, ya que requieren iniciar sesión en una aplicación cliente o en información relacionada con la identidad, ambas provistas por OIDC.
¿Por qué de repente necesitamos todas estos antecedentes? La autenticación de formularios podría funcionar cuando se está creando una aplicación ASP.NET estándar de n niveles o incluso una aplicación basada en servicios que se ejecute en el mismo contexto. Pero en estos días, la mayoría de las aplicaciones modernas están basadas en API, con una API completamente separada de cualquier cliente que lo consuma (esto es realmente una de las restricciones fundamentales impuestas por una arquitectura basada en REST).
La aplicación cliente que consume esa API puede ser una aplicación ASP.NET MVC, que consume la API del servidor, pero también podría ser una aplicación móvil o una aplicación basada en JavaScript (por ejemplo, Angular). En este caso, la API Se consume desde un dispositivo cliente. La autenticación de formularios, obviamente, no es adecuada para esos escenarios. Pero … el envío de un string de nombre de usuario / contraseña en cada HttpRequest a tu API realmente no es algo que quieras hacer.
Los tokens representan el consentimiento, por ejemplo: concedido por el usuario, a la aplicación cliente, para acceder a una API — normalmente a través de ámbitos, en la jerga OAuth2.
Su aplicación cliente debería — de alguna manera — obtener un token. Ese símbolo se puede utilizar en el cliente, o se puede pasar a la API, que se utiliza en ese nivel para autorizar el acceso. Hace un tiempo, la gente escribía “servicios simbólicos” para eso. Típicamente: una llamada a un punto de inicio auto-creado / de inicio de sesión, que aceptaría su nombre de usuario / contraseña y devolvería un Token Web JSON.
Pero simplemente enviar su nombre de usuario / contraseña a una acción auto-creada en una API y obtener un token a cambio no es un buen ajuste para muchas aplicaciones, ni una buena idea. Aún así, es necesario que comparta su nombre de usuario / contraseña con esa API, que podría estar bien para su propia aplicación de confianza (aunque no soy un gran fans), pero es una muy mala idea para aplicaciones de terceros, incluidas otras aplicaciones. Que podría vivir en su empresa. Por otra parte, una vez que comenzamos a crear extremos como estos nosotros mismos, estamos esencialmente reinventando la rueda. Tenemos que implementar la expiración nosotros mismos. Tenemos que implementar la validación de token. Tenemos que implementar el cierre de sesión. Es posible que desee implementar soporte de token de referencia. Necesitaremos separar identidad y acceso, y así sucesivamente. En resumen, los errores son casi inevitables.
Introduzca el protocolo OAuth2. El protocolo OAuth2 define una forma de obtener de forma segura un tipo específico de token (“obtener autorización”) : un token de acceso. Lo hace a través de uno de los diferentes flujos / subvenciones como se define en el RFC. Es su responsabilidad elegir el flujo correcto, dependiendo del tipo de aplicación que esté construyendo.
Este tipo de token se utiliza para autorizar el acceso a esa API. Por supuesto, sigue siendo la API que elige si el consentimiento que contiene el token de acceso es suficiente para permitir el acceso. Por lo tanto, su aplicación cliente debe obtener un token de acceso de un servicio de token de seguridad (como IdentityServer) a través de una concesión / flujo específico y pasar ese token de acceso en cada llamada a la API.
Sin embargo, los clientes de acceso OAuth2 no deben utilizarse para la autenticación: el protocolo no es lo suficientemente estricto para permitirlo de forma segura. Sin embargo, OIDC, construido sobre OAuth2, define un nuevo tipo de token: un token de identidad. Y que se puede utilizar para la autenticación.
El ejemplo arquetípico es una aplicación ASP.NET MVC que llama a una API a través de una instancia de HttpClient. Utiliza el token de identidad para iniciar sesión en la aplicación ASP.NET MVC y utiliza el token de acceso para acceder a la API.
En este caso, esa aplicación cliente es un cliente Xamarin. Pero … no hay ningún uso real para iniciar sesión en un cliente de este tipo. Los clientes móviles (Xamarin, iOS nativo, Android, Windows Phone, …) se despliegan en un teléfono, un dispositivo que no es de confianza. No podemos no entregamos código dependiendo de la identidad del usuario: el código ya está presente en el dispositivo cliente. El mismo principio es válido para clientes basados ​​en JavaScript, como un cliente Angular. Esto es contrario a lo que podemos hacer con una tecnología de servidor, por ejemplo: una aplicación ASP.NET MVC. En esos tipos de aplicaciones, podemos bloquear eficazmente el acceso a partes del código — nunca se ejecutarán, los resultados nunca se servirán a su navegador. Para los clientes móviles, normalmente necesitamos fichas de acceso más de lo que necesitamos fichas de identidad.
Sin embargo, los tokens de identidad también se utilizan para que estos tipos de clientes obtengan información relacionada con la identidad del token (alternativamente, también puede utilizar el punto final de UserInfo). Por lo tanto, aunque realmente no estamos iniciando sesión en el cliente como lo haríamos en un cliente ASP.NET MVC, OpenID Connect tiene sentido ya que permite el acceso a la información relacionada con la identidad, ya sea directamente contenida en un token de identidad o por Utilizando un token de acceso que contiene ámbitos de identidad para acceder al punto final UserInfo. Junto a eso — quizás aún más importante -, OIDC es más estricto que OAuth2 (como se mencionó anteriormente), lo que significa que añade características de seguridad adicionales (entonces, por ejemplo) — Yo aconsejaría utilizar siempre OIDC, incluso si no Necesitan fichas de identidad.
Ahora, ¿cómo encaja IdentityServer en esta historia? Si usted lee a través de los RFC, notará que hay una gran cantidad de implementación que tiene que suceder a nivel de servidor. Esto no es algo que usted normalmente quiere hacer usted mismo: Dominick Baier y Brock Allen han hecho esto por nosotros. IdentityServer implementa los estándares OAuth2 y OIDC, entre otros. Lo que nosotros, como desarrolladores de las aplicaciones cliente y API tenemos que manejar es la parte del cliente de los estándares y asegurando que nuestra API pueda trabajar con esos tokens.
Hay un gran tutorial sobre cómo configurar IdentityServer en la documentación , en caso de que no lo haya hecho antes. El tutorial también contiene un ejemplo sobre cómo proteger su API.
Uff, hasta ahora para ese curso acelerado — he cortado algunas esquinas aquí y allá, pero esta es la esencia de la misma. En la aplicación de ejemplo.
La Aplicación de Ejemplo de Xamarin Forms
Como sabemos ahora, es importante utilizar el flujo correcto para el tipo de aplicación que va a construir. No utilizar el flujo correcto podría abrirse a riesgos que no desea; Por ejemplo: un flujo de credenciales de cliente, que se basa en un secreto de cliente, no debe utilizarse de las aplicaciones que se ejecutan en el cliente: no tienen medios de almacenar con seguridad ese secreto, haciendo que el secreto esencialmente inútil.
El flujo aconsejado para una aplicación móvil (nativa) es el flujo implícito, de acuerdo con la especificación actual, aunque también puede utilizar el flujo de código de autorización o el flujo híbrido. Hay bastante discusión sobre esto que está sucediendo actualmente, y esta postura podría cambiar en el futuro (cercano) (probablemente favoreciendo el flujo híbrido). Al igual que con todas las cosas relacionadas con la seguridad: el trabajo nunca es realmente terminado (que es, incidentalmente, bastante buenas noticias para mi seguridad laboral ;-)).
De todos modos, he implementado esto utilizando el flujo implícito, pero los otros flujos se implementaría de la misma manera.
Este es un flujo basado en la redirección, por lo que necesitaremos usar un WebView en nuestra aplicación Xamarin Forms. La idea general es que utilizaremos ese WebView para navegar hasta el punto final de autorización en el nivel de Identity Server, pasando los tipos de ámbitos y respuestas que necesitamos. En la página LoginView.xaml, hay una WebView oculta:
codigo
public void StartFlow(string responseType, string scope)
{
var authorizeRequest =
new AuthorizeRequest(“https://localhost:44333/core/connect/authorize”);

// dictionary with values for the authorize request
var dic = new Dictionary<string, string>();
dic.Add(“client_id”, “implicitclient”);
dic.Add(“response_type”, responseType);
dic.Add(“scope”, scope);
dic.Add(“redirect_uri”, “https://xamarin-oidc-sample/redirect”);
dic.Add(“nonce”, Guid.NewGuid().ToString(“N”));

// add CSRF token to protect against cross-site request forgery attacks.
_currentCSRFToken = Guid.NewGuid().ToString(“N”);
dic.Add(“state”, _currentCSRFToken);

var authorizeUri = authorizeRequest.Create(dic);

wvLogin.Source = authorizeUri;
wvLogin.IsVisible = true;
}
El código es de la muestra en el proyecto IdentityServer3.Samples, pero el proyecto autónomo también contiene código)
Como estamos trabajando con OIDC, debemos incluir un token en esa solicitud. Para protegernos de los ataques CSRF, debemos incluir un token CSRF, que es esencialmente un valor aleatorio, no adivinable, que se devolverá al cliente. Una vez que se ha recuperado, tenemos que comprobar que coincide con el valor que enviamos en la solicitud inicial.
Por lo tanto, lo primero que debe hacer: crear el URI en el punto final de autorización en el nivel IdentityServer. He utilizado el paquete IdentityModel para esto, lo que ayuda mucho con la creación de los URIs correctos y el análisis de los resultados. El método StartFlow contiene el código para crear el URI y navegar el WebView a ese URI.

Los botones de la muestra llaman a ese método, pasando en response_type & scopes. Por ejemplo, esta pieza de código pedirá un token de identidad y un token de acceso:
Private void GetIdTokenAndAccessToken (object sender, EventArgs e)
{
// al preguntar a ambos, podemos pedir ámbitos relacionados con la identidad
// así como ámbitos de recursos
StartFlow (“id_token token”, “openid profile read write”);
}
Una vez que el URI de WebView esté configurado con el URI que acabamos de crear, mostrará la página de inicio de sesión de IdentityServer, donde tendrá que proporcionar sus credenciales (alice / alice para el ejemplo de IdentityServer3.Samples, Kevin / secreto para el ejemplo independiente).
A continuación se analizan los tokens una vez que se redirigen. Estos tokens se incluyen en el URI y podemos analizarlos captando el evento Navigated del WebView y comprobando si el URI comienza con el URI de redirección que pasamos al crear el URI de autorización. AuthorizeResponse también forma parte del paquete IdentityModel. No olvide comprobar el token CSRF para protegerse contra ataques CSRF.
private void WvLogin_Navigating(object sender, WebNavigatingEventArgs e)
{
if (e.Url.Contains(“https://xamarin-oidc-sample/redirect”))
{
wvLogin.IsVisible = false;

// parse response
_authResponse = new AuthorizeResponse(e.Url);

// CSRF check
var state = _authResponse.Values[“state”];
if (state != _currentCSRFToken)
{
txtResult.Text = “CSRF token doesn’t match”;
return;
}

string decodedTokens = “”;
// decode tokens
if (!string.IsNullOrWhiteSpace(_authResponse.IdentityToken))
{
decodedTokens += “Identity token \r\n”;
decodedTokens += DecodeToken(_authResponse.IdentityToken) + “\r\n”;
}

if (!string.IsNullOrWhiteSpace(_authResponse.AccessToken))
{
decodedTokens += “Access token \r\n”;
decodedTokens += DecodeToken(_authResponse.AccessToken);
}

txtResult.Text = decodedTokens;
}
}
Y eso es todo lo que hay. A partir de este momento, usted tiene el token (s) que usted pidió, que contiene los ámbitos demandados. Puede utilizar el token de identidad para obtener información relacionada con la identidad y puede utilizar el token de acceso para acceder a su API.

Eso es todo por ahora, feliz Codificación!
Fuente y repositorio
Articulo original,
IdentityModel/IdentityModel.OidcClient2
IdentityModel.OidcClient2 – Certified C#/NetStandard OpenID Connect Client Library for native mobile/desktop…github.com
https://www.kevindockx.com/working-with-oauth2-and-openid-connect-from-a-xamarin-forms-application-using-identityserver3/

Implementación del patrón MVVM con Prism

El patrón Model-View-ViewModel (MVVM) ayuda a separar de forma limpia la lógica de presentación y de negocios de la aplicación desde su interfaz de usuario (UI). Mantener una separación limpia entre la lógica de la aplicación y la interfaz de usuario ayuda a abordar numerosos problemas de desarrollo y diseño y puede hacer su aplicación mucho más fácil de probar, mantener y evolucionar. También puede mejorar enormemente las oportunidades de reutilización de código y permite a los desarrolladores y diseñadores de interfaces de usuario colaborar más fácilmente al desarrollar sus respectivas partes de la aplicación.

Utilizando el patrón MVVM, la interfaz de usuario de la aplicación y la presentación subyacente y la lógica empresarial se dividen en tres clases independientes: la vista, que encapsula la interfaz de usuario y la lógica de la interfaz de usuario; El modelo de vista, que encapsula la lógica y el estado de la presentación; Y el modelo, que encapsula la lógica empresarial y los datos de la aplicación.

Prism incluye ejemplos e implementaciones de referencia que muestran cómo implementar el patrón MVVM en una aplicación Xamarin Form. La Biblioteca Prism también proporciona características que pueden ayudarle a implementar el patrón en sus propias aplicaciones. Estas características incorporan las prácticas más comunes para implementar el patrón MVVM y están diseñadas para soportar la testeabilidad y para trabajar bien con Visual Studio.

Este Post proporciona una visión general del patrón MVVM y describe cómo implementar sus características fundamentales.

Responsabilidades y características de la clase

El patrón MVVM es una variante estrecha del patrón del modelo de presentación, optimizado para aprovechar algunas de las capacidades principales de Xamarin Form, como el enlace de datos, las plantillas de datos, los comandos y los comportamientos.

En el patrón MVVM, la vista encapsula la interfaz de usuario y cualquier lógica de interfaz de usuario, el modelo de vista encapsula la lógica y el estado de la presentación y el modelo encapsula la lógica empresarial y los datos. La vista interactúa con el modelo de vista a través de enlace de datos, comandos y eventos de notificación de cambios. El modelo de vista consulta, observa y coordina actualizaciones del modelo, convirtiendo, validando y agregando datos según sea necesario para mostrarlos en la vista.

La siguiente ilustración muestra las tres clases MVVM y su interacción.

Las clases MVVM y sus interacciones

Las clases MVVM y sus interacciones

Al igual que con todos los patrones de presentación separados, la clave para usar el patrón MVVM reside efectivamente en comprender la forma adecuada de factorizar el código de su aplicación en las clases correctas y en comprender las formas en que estas clases interactúan en varios escenarios. Las siguientes secciones describen las responsabilidades y características de cada una de las clases en el patrón MVVM.

La clase View

La responsabilidad de la vista es definir la estructura y la apariencia de lo que el usuario ve en la pantalla. Idealmente, el code-behind de una vista contiene sólo un constructor que llama al método InitializeComponent . En algunos casos, el code-behind puede contener código de lógica de interfaz de usuario que implementa comportamiento visual que es difícil o ineficiente para expresar en XAML (Extensible Application Markup Language), como animaciones complejas o cuando el código necesita manipular directamente elementos visuales que son Parte de la vista. No debe poner ningún código lógico en la vista que necesita para la prueba de unidad. Normalmente, el código lógico en el código de la vista posterior será probado a través de un enfoque de prueba de automatización de la interfaz de usuario.

En Xamarin Form, las expresiones de enlace de datos en la vista se evalúan en función de su contexto de datos. En MVVM, el contexto de datos de la vista se establece en el modelo de vista. El modelo de vista implementa propiedades y comandos a los que la vista puede enlazar y notifica la vista de cualquier cambio en el estado a través de eventos de notificación de cambios. Normalmente existe una relación uno a uno entre una vista y su modelo de vista.

Normalmente, las vistas son clases control- derivadas o UserControl- derivadas. Sin embargo, en algunos casos, la vista puede estar representada por una plantilla de datos, que especifica los elementos de la interfaz de usuario que se utilizarán para representar visualmente un objeto cuando se muestre. Mediante el uso de plantillas de datos, un diseñador visual puede definir fácilmente cómo se renderizará un modelo de vista o modificar su representación visual predeterminada sin cambiar el objeto subyacente ni el comportamiento del control que se utiliza para mostrarlo.

Las plantillas de datos pueden considerarse como vistas que no tienen ningún código por detrás. Están diseñados para enlazar a un tipo de modelo de vista específico cada vez que se requiere que se muestre en la interfaz de usuario. En tiempo de ejecución, la vista, tal como se define en la plantilla de datos, se instanciará automáticamente y su contexto de datos se establecerá en el modelo de vista correspondiente.

En Xamarin Form, puede asociar una plantilla de datos con un tipo de modelo de vista en el nivel de aplicación. Xamarin Form aplicará automáticamente la plantilla de datos a cualquier objeto de modelo de vista del tipo especificado cada vez que se muestren en la interfaz de usuario. Esto se conoce como plantilla de datos implícita. La plantilla de datos se puede definir en línea con el control que la utiliza o en un diccionario de recursos fuera de la vista principal y se agrupa declarativamente en el diccionario de recursos de la vista.

En resumen, la vista tiene las siguientes características clave:

  • La vista es un elemento visual, como una ventana, una página, un control de usuario o una plantilla de datos. La vista define los controles contenidos en la vista y su diseño visual y estilo.
  • La vista hace referencia al modelo de vista a través de su propiedad DataContext . Los controles de la vista están vinculados a las propiedades y comandos expuestos por el modelo de vista.
  • La vista puede personalizar el comportamiento de enlace de datos entre la vista y el modelo de vista. Por ejemplo, la vista puede utilizar convertidores de valores para formatear los datos que se mostrarán en la interfaz de usuario o puede utilizar reglas de validación para proporcionar validación adicional de datos de entrada al usuario.
  • La vista define y maneja el comportamiento visual de la interfaz de usuario, como animaciones o transiciones que pueden ser activadas a partir de un cambio de estado en el modelo de vista o mediante la interacción del usuario con la interfaz de usuario.
  • La clave de la vista puede definir la lógica de la interfaz de usuario para implementar un comportamiento visual que es difícil de expresar en XAML o que requiere referencias directas a los controles de interfaz de usuario específicos definidos en la vista.

La clase de modelo de vista

El modelo de vista en el patrón MVVM encapsula la lógica de presentación y los datos de la vista. No tiene referencia directa a la vista o ningún conocimiento sobre la implementación o el tipo específico de la vista. El modelo de vista implementa propiedades y comandos a los que la vista puede enlazar datos y notifica la vista de cualquier cambio de estado a través de eventos de notificación de cambios. Las propiedades y comandos que proporciona el modelo de vista definen la funcionalidad que ofrece la interfaz de usuario, pero la vista determina cómo se va a procesar dicha funcionalidad.

El modelo de vista es responsable de coordinar la interacción de la vista con cualquier clase de modelo que se requiera. Normalmente, existe una relación de uno a muchos entre el modelo de vista y las clases de modelo. El modelo de vista puede optar por exponer clases de modelo directamente a la vista para que los controles en la vista puedan enlazar datos directamente a ellos. En este caso, las clases de modelo deberán diseñarse para soportar la vinculación de datos y los eventos de notificación de cambios relevantes.

El modelo de vista puede convertir o manipular datos de modelo para que pueda ser consumido fácilmente por la vista. El modelo de vista puede definir propiedades adicionales para soportar específicamente la vista; Estas propiedades normalmente no forman parte del modelo (o no pueden añadirse). Por ejemplo, el modelo de vista puede combinar el valor de dos campos para facilitar la presentación de la vista, o puede calcular el número de caracteres restantes para la entrada de campos con una longitud máxima. El modelo de vista también puede implementar lógica de validación de datos para garantizar la coherencia de los datos.

El modelo de vista también puede definir estados lógicos que la vista puede utilizar para proporcionar cambios visuales en la interfaz de usuario. La vista puede definir cambios de diseño o estilo que reflejen el estado del modelo de vista. Por ejemplo, el modelo de vista puede definir un estado que indica que los datos se envían de forma asíncrona a un servicio web. La vista puede mostrar una animación durante este estado para proporcionar retroalimentación visual al usuario.

Normalmente, el modelo de vista definirá comandos o acciones que se pueden representar en la interfaz de usuario y que el usuario puede invocar. Un ejemplo común es cuando el modelo de vista proporciona un comando Enviar que permite al usuario enviar datos a un servicio web oa un repositorio de datos. La vista puede elegir representar ese comando con un botón para que el usuario pueda hacer clic en el botón para enviar los datos. Normalmente, cuando el comando no está disponible, su representación de interfaz de usuario asociada se deshabilita. Los comandos proporcionan una forma de encapsular las acciones del usuario y separarlas de forma clara de su representación visual en la interfaz de usuario.

En resumen, el modelo de vista tiene las siguientes características clave:

  • El modelo de vista es una clase no visual y no se deriva de ninguna clase base de Xamarin Form. Encapsula la lógica de presentación requerida para soportar un caso de uso o tarea de usuario en la aplicación. El modelo de vista es comprobable independientemente de la vista y el modelo.
  • Normalmente, el modelo de vista no hace referencia directa a la vista. Implementa propiedades y comandos a los que la vista puede enlazar datos. Notifica la vista de cualquier cambio de estado a través de eventos de notificación de cambios a través de las interfaces INotifyPropertyChanged e INotifyCollectionChanged .
  • El modelo de vista coordina la interacción de la vista con el modelo. Puede convertir o manipular datos para que pueda ser consumido fácilmente por la vista y puede implementar propiedades adicionales que pueden no estar presentes en el modelo. También puede implementar validación de datos a través de las interfaces IDataErrorInfo o INotifyDataErrorInfo .
  • El modelo de vista puede definir estados lógicos que la vista puede representar visualmente al usuario.
Gg405484.note (es-es, PandP.40) .gifNota:
Muchas veces, determinar dónde debe implementarse determinada funcionalidad no es obvia. La regla general es: Cualquier cosa relacionada con el aspecto visual específico de la interfaz de usuario en la pantalla y que podría volver a denominarse más tarde (incluso si actualmente no está planeando volver a diseñarlo) debe entrar en la vista; Cualquier cosa que sea importante para el comportamiento lógico de la aplicación debe entrar en el modelo de vista. Además, debido a que el modelo de vista no debe tener conocimiento explícito de los elementos visuales específicos de la vista, el código para manipular de forma programática elementos visuales dentro de la vista debe residir en el código de la vista o estar encapsulado en un comportamiento. Del mismo modo, el código para recuperar o manipular elementos de datos que se van a mostrar en la vista a través del enlace de datos debe residir en el modelo de vista.

La Clase Modelo

El modelo en el patrón MVVM encapsula la lógica empresarial y los datos. La lógica de negocio se define como cualquier lógica de aplicación que se ocupe de la recuperación y gestión de datos de aplicación y para asegurarse de que se imponen las reglas de negocio que garantizan la coherencia y la validez de los datos. Para maximizar las oportunidades de reutilización, los modelos no deben contener ningún comportamiento de uso específico de caso o de usuario específico de la tarea o la lógica de la aplicación.

Normalmente, el modelo representa el modelo de dominio del cliente para la aplicación. Puede definir estructuras de datos basadas en el modelo de datos de la aplicación y en cualquier lógica de validación y de negocio. El modelo también puede incluir el código para admitir el acceso a los datos y el almacenamiento en caché, aunque normalmente se emplea un repositorio o servicio de datos por separado. A menudo, el modelo y la capa de acceso a datos se generan como parte de una estrategia de acceso a datos o de servicio.

Normalmente, el modelo implementa las facilidades que hacen que sea fácil de enlazar a la vista. Esto generalmente significa que admite la notificación de propiedad y colección modificada a través de las interfaces INotifyPropertyChanged e INotifyCollectionChanged . Las clases de modelos que representan colecciones de objetos normalmente derivan de la clase ObservableCollection <T> , que proporciona una implementación de la interfaz INotifyCollectionChanged .

El modelo también puede admitir validación de datos y notificación de errores a través de las interfaces IDataErrorInfo (o INotifyDataErrorInfo ). Las interfaces IDataErrorInfo e INotifyDataErrorInfo permiten que el enlace de datos de Xamarin Form sea notificado cuando los valores cambian para que la interfaz de usuario pueda actualizarse. También permiten el soporte para la validación de datos y la generación de informes de errores en la capa de IU.

Gg405484.note (es-es, PandP.40) .gifNota:
¿Qué pasa si sus clases de modelo no implementan las interfaces requeridas? 
A veces necesitará trabajar con objetos de modelo que no implementen las interfaces INotifyPropertyChanged , INotifyCollectionChanged , IDataErrorInfo o INotifyDataErrorInfo . En esos casos, es posible que el modelo de vista necesite ajustar los objetos del modelo y exponer las propiedades necesarias a la vista. Los valores de estas propiedades serán proporcionados directamente por los objetos del modelo. El modelo de vista implementará las interfaces necesarias para las propiedades que expone para que la vista pueda enlazar datos fácilmente a ellas.

El modelo tiene las siguientes características clave:

  • Las clases de modelo son clases no visuales que encapsulan los datos y la lógica empresarial de la aplicación. Son responsables de gestionar los datos de la aplicación y de garantizar su coherencia y validez encapsulando las reglas empresariales y la lógica de validación de datos requeridas.
  • Las clases de modelo no hacen referencia directa a las clases de modelo de vista o vista y no tienen dependencia de cómo se implementan.
  • Las clases de modelo normalmente proporcionan eventos de notificación de cambio de propiedad y de colección a través de las interfaces INotifyPropertyChanged e INotifyCollectionChanged . Esto les permite ser fácilmente vinculados a los datos en la vista. Las clases de modelo que representan colecciones de objetos normalmente derivan de la clase ObservableCollection <T> .
  • Normalmente, las clases de modelo proporcionan validación de datos y notificación de errores a través de las interfaces IDataErrorInfo o INotifyDataErrorInfo .
  • Las clases de modelo suelen utilizarse conjuntamente con un servicio o repositorio que encapsula el acceso a los datos y el almacenamiento en caché.

Interacciones de clase

El patrón MVVM proporciona una separación clase entre la interfaz de usuario de su aplicación, su lógica de presentación y su lógica de negocio y datos, separándolos en clases separadas. Por lo tanto, al implementar MVVM, es importante que el código de la aplicación se aplique a las clases correctas, tal como se describe en la sección anterior.

La vista bien diseñada, el modelo de vista y las clases de modelo no sólo encapsularán el tipo correcto de código y comportamiento; También se diseñarán de modo que puedan interactuar fácilmente entre sí a través de enlaces de datos, comandos y interfaces de validación de datos.

Las interacciones entre la vista y su modelo de vista son quizás las más importantes a considerar, pero las interacciones entre las clases de modelo y el modelo de vista también son importantes. En las siguientes secciones se describen los distintos patrones de estas interacciones y se describe cómo diseñarlas cuando implementen el patrón MVVM en sus aplicaciones.

El enlace de datos

El enlace de datos desempeña un papel muy importante en el patrón MVVM. Xamarin Form proporciona poderosas capacidades de enlace de datos. Su modelo de vista y (idealmente) sus clases de modelo se deben diseñar para apoyar la vinculación de datos para que puedan aprovechar estas capacidades. Normalmente, esto significa que deben implementar las interfaces correctas.

El enlace de datos de Xamarin Form admite varios modos de vinculación de datos. Con vinculación de datos unidireccional, los controles de interfaz de usuario pueden enlazarse a un modelo de vista para que reflejen el valor de los datos subyacentes cuando se muestre la presentación. El enlace de datos bidireccional también actualizará automáticamente los datos subyacentes cuando el usuario lo modifique en la interfaz de usuario.

Para garantizar que la interfaz de usuario se mantiene actualizada cuando los datos cambian en el modelo de vista, debe implementar la interfaz de notificación de cambios adecuada. Si define propiedades que pueden ser datos enlazados, debe implementar la interfaz INotifyPropertyChanged . Si el modelo de vista representa una colección, debe implementar la interfaz INotifyCollectionChanged o derivar de la clase ObservableCollection <T> que proporciona una implementación de esta interfaz. Ambas interfaces definen un evento que se genera cada vez que se cambian los datos subyacentes. Todos los controles vinculados a datos se actualizarán automáticamente cuando se generen estos eventos.

En muchos casos, un modelo de vista definirá las propiedades que devuelven objetos (y que, a su vez, pueden definir propiedades que devuelven objetos adicionales). El enlace de datos de Xamarin Form

admite el enlace a propiedades anidadas a través de la propiedad Path . Por lo tanto, es muy común que el modelo de vista de una vista devuelva referencias a otras clases de modelo o modelo de vista. Todas las clases de modelo y modelo de vista accesibles a la vista deben implementar las interfaces INotifyPropertyChanged o INotifyCollectionChanged , según corresponda.

En las siguientes secciones se describe cómo implementar las interfaces necesarias para soportar la vinculación de datos dentro del patrón MVVM.

Implementación de INotifyPropertyChanged

La implementación de la interfaz INotifyPropertyChanged en su modelo de vista o clases de modelo les permite proporcionar notificaciones de cambios a cualquier control enlazado a datos en la vista cuando cambia el valor de la propiedad subyacente. La implementación de esta interfaz es sencilla, como se muestra en el siguiente ejemplo de código.

public class MyViewModel : BindableBase
{
    public ICollectionView Customers { get; private set; }

    public MyViewModel( ObservableCollection<Customer> customers )
    {
        // Initialize the CollectionView for the underlying model
        // and track the current selection.
        Customers = new ListCollectionView( customers );
        
        Customers.CurrentChanged +=SelectedItemChanged;
    }

    private void SelectedItemChanged( object sender, EventArgs e )
    {
        Customer current = Customers.CurrentItem as Customer;
        ...
    }
    ...
}


 

Azure Machine Learning

Creación de aplicaciones inteligentes con Azure Aprendizaje de máquinas

 

Visión de conjunto

El aprendizaje automático, que facilita la analítica predictiva utilizando grandes volúmenes de datos mediante el uso de algoritmos que iterativamente aprender de los datos, es una de las áreas de más rápido crecimiento de la informática. Sus usos van desde la detección de fraudes de tarjetas de crédito y automóviles autodirigidos hasta reconocimiento óptico de caracteres (OCR) y recomendaciones de compras en línea. Nos hace más inteligentes haciendo que las computadoras sean más inteligentes. Y su utilidad sólo aumentará a medida que más y más datos estén disponibles y el deseo de realizar un análisis predictivo a partir de esos datos crece, también.

Azure Machine Learning es un servicio de predicción analítica basado en la nube que ofrece una experiencia simplificada para los científicos de datos de todos los niveles de habilidad. Está acompañado por el Estudio de Aprendizaje de la Máquina de Azure (ML Studio), que es una herramienta basada en navegador que proporciona una interfaz fácil de usar, arrastrar y soltar para la construcción de modelos de aprendizaje de máquina. Viene con una biblioteca de ahorro de tiempo experimentos y cuenta con mejores algoritmos de clase desarrollados y probados en el mundo real por empresas de Microsoft como Bing. Y su soporte incorporado para R y Python significa que puede crear scripts personalizados para personalizar su modelo. Una vez que haya construido y entrenado su modelo en ML Studio, puede exponerlo fácilmente como un servicio Web que es consumible desde una variedad de lenguajes de programación,

 

XamarinFest Chile Resumen de la experiencia

Ha pasado algunas semanas desde que ya termino Xamarin Fest Chile y la experiencia fue buena a pesar de los por menores de organizar un evento de tales características en Chile, la verdad que la idea de organizar el evento fue una iniciativa personal al buscar eventos de  Xamarin en Chile y no encontrar eventos relacionados, por lo cual busque en google hasta llegar con Xamarin Fest https://xamarinfestlatam.azurewebsites.net/ Solo inscribí el evento teniendo presente que seria un laboratorio de unas 30 personas donde se realizaría una demostración de una aplicación conectada a la nube de azure.

El evento fue realizado en 2 días seguidos pensando en universitarios (estudiantes) y personas que trabajen por lo cual seria un viernes y un sábado, la verdad no sabia lo que me esperaba en el camino con todo el esfuerzo de realizar 2 días seguidos estos laboratorios sin tener la experiencia previa.

De todas formas y con la ayuda de Mabel Geronimo y Fernando Mejia de Microsoft a quien doy las gracias por todo el apoyo logramos ejecutar el evento correctamente.

El día viernes logramos realizar el evento en las oficinas de microsoft donde el MVP de Xamarin en Chile Ivan Toledo nos compartió su experiencia sobre MVVM y Mobile Center.

Mas información sobre mobile center en:

https://mobile.azure.com/login

Video del evento a continuación. https://www.youtube.com/watch?v=sw2pAIgGdVQ

El segundo día hablamos sobre Xamarin y Azure sus bondades y las formas de conexión

Se pueden encontrar los repositorios de los eventos a continuación

https://github.com/lawebdeprogramador/Contenido-Eventos

https://github.com/lawebdeprogramador/XamarinAllienceFinal

 

Fotos del evento a continuación:

En conclusión.

Fue una experiencia motivante y un desafío personal lo cual personalmente me lleno de ideas nuevas para seguir compartiendo con la comunidad de programadores en Chile.

Espero en el futuro seguir organizando eventos de este tipo, ya que se logran muchas experiencias, se conocen nuevas personas y talentos que pueden aportar mucho a la comunidad.

 

 

 

 

 

Xamarin Form introducción complemento XamarinFest 2017

 

Hoy en día, crear aplicaciones móviles para múltiples plataformas supone todo un reto para los desarrolladores. Tratar de abordar un desarrollo usando los toolkits nativos de cada sistema requiere de una cantidad enorme de conocimientos específicos para cada uno de ellos. Nos encontraremos con un panorama enormemente complejo, con múltiples lenguajesvarios entornos de desarrolloAPIs de todos los colores. Xamarin trata de poner solución a esta problemática ofreciéndonos un conjunto de herramientas que nos permitirá desarrollar aplicaciones nativas, compartiendo la mayor cantidad de código, entre las plataformas más importantes: AndroidiOS y Windows Phone.

Este artículo va dirigido a desarrolladores que estén interesados en comenzar a crear aplicaciones cross-platform nativas con Xamarin, sería recomendable que estuviesen familiarizados con el lenguaje C# y/o con el SDK de iOS o Android, aunque no es imprescindible. En la primera parte de la entrada trataré algunas generalidades como la problemática del desarrollo multiplataforma, las características claves de Xamarin, la instalación y puesta en marcha y la cuando elegir entre Xamarin Tradicional o Xamarin Forms. En la segunda parteme centraré en Xamarin.Forms y en sus elementos clave;  por último, veremos una pequeña introducción a la implementación del patrón MVVM en Xamarin Forms.

La problemática del desarrollo multiplataforma

Como podemos observar en la siguiente tabla, cada plataforma cuenta con su propio entorno de desarrollo integrado (IDE), con uno o varios lenguajes de programación, con un lenguaje especifico para las vistas, y por si fuera poco los patrones de diseño a aplicar difieren entre las diferentes plataformas.

IOS ANDROID WINDOWS
IDE XCode Android Studio Visual Studio
Lenguaje ObjectiveC o Swift Java C#
Vistas Storyboard o XIBS AXML XAML
Patrón de diseño MVC MVC MVVM

Abordar todos estos aspectos requiere de una cantidad de enorme de conocimientos por parte del desarrollador y, por otro lado, no parece ser eficiente tener que reescribir la lógica de negocio para cada uno de los sistemas.

¿Que opciones tenemos? Apps híbridas o nativas

Tradicionalmente, cuando hablamos de tecnologías multiplataforma, pensamos en un enfoque minimalista: reducir nuestra implementación/desarrollo a un mínimo denominador en todas las plataformas. Esto es lo que se propone en las aplicaciones híbridas desarrolladas con tecnologías del tipo PhoneGap/Cordova, en las cuales escribimos códigohtml y javascript  que tiene que ser interpretado por un navegador web. Este tipo de soluciones no consigue igualar la respuesta y la experiencia de usuario de una app nativa. Por poner un ejemplo, Mark Zuckerberg (CEO de Facebook), reconoció que el mayor error que habían cometido en la trayectoria de Facebook fue crear  en un primer momento una app híbrida en lugar de una nativa.

Mark Zuckerberg: nuestro mayor error ha sido crear en un principio una app híbrida en lugar de nativa 

Xamarin nos ofrece un enfoque multiplataforma diferente, ya que nos facilita la tarea de desarrollar cualquier tipo de aplicación/juego de forma nativa para las plataformas más usadas: iOS, Android y Windows. Para ello nos brinda acceso al 100% de las APIS nativas + las APIs comunes de .NET, con un mismo lenguaje de programación C#.

Existen alternativas interesantes a Xamarin que también proponen un enfoque nativo, como puede ser React Native de Facebook (aún en beta) , que permite escribir apps para android e iOS Nativas en Javascript con el estilo de React. O, Ruby Motion, una tecnología que nos permite realizar apps para Android e iOS con Ruby, si RoR forma parte de tu stack esta plataforma es más que interesante. Aunque sin duda, por aceptacióncuota, comunidad y evolución brilla con luz propia Xamarin.

react-native-rubymotion

Características

 

Compartir código:Además de compartir un mismo lenguaje y entorno de desarrollo, podemos utilizar un mismo patrón de desarrollo.

Completa cobertura de las APIs de iOS y Android: Tenemos todas las APIs disponibles con C#, cualquier cosa que se pueda hacer con Objective-C/Swift o Java, se puede hacer con C# y Xamarin.

api-xamarin

Aplicaciones nativas:Las aplicaciones desarrolladas con Xamarin son 100% nativas.

Siempre actualizado: Xamarin suele añadir soporte el mismo día del lanzamiento oficial de una actualización.

Open source y gratis: Tras la compra de Xamarin por parte de Microsoft, pasó a ser Open Source y gratuito.

Instalación de Xamarin

En Mac OS
Para instalar Xamarin en Mac OS, tan solo tenemos que descargar el instalador y a continuación un asistente nos guiará en la instalación de Xamarin Studio y los SDKs  de las diferentes plataformas.

En Windows:
Para comenzar a trabajar con Xamarin en Windows se debe realizar la descarga de Visual Studio Community. Tras ejecutar el instalador tenemos la posibilidad de elegir entre una instalación típica o personalizada. Escogemos personalizada y seleccionamos el checkbox de Xamarin dentro del apartado de desarrollo móvil multiplataforma.

Para compilar y acceder a opciones como el editor visual de iOS necesitamos de forma inevitable tener conexión con un Mac. Todo el proceso de conexión se realiza de forma prácticamente transparente desde Visual Studio a través de la herramienta Xamarin Mac Agent por medio de una conexión ssh.

Xamarin Tradicional vs Xamarin Forms

Antes de empezar a desarrollar con  Xamarin debemos elegir si utilizar Xamarin Tradicional(Xamarin.iOS y Xamarin.Android) o Xamarin Forms para crear nuestro proyecto, aunque algunos expertos de la comunidad como @_jmgomez_ ya plantean algunas soluciones “fuera de la caja” (artículo).

En Xamarin tradicional, se puede compartir toda la lógica de la aplicación entre las diferentes plataformas, a excepción de la interfaz de usuario, la cual será independiente para cada una de las mismas. En cambio, Xamarin Forms añade una capa de abstracción sobre la UI que permite compartir, además de la lógica de negocio, la interfaz de usuario, aumentando consigo la reutilización de código.

¿Cuando escoger uno u otro?
Xamarin tradicional es idóneo cuando se requiere un nivel muy elevado de personalización de la interfaz de usuario para cada una de las plataformas, siendo más importante el nivel personalización de la UI que la cantidad de código compartido; mientras que Xamarin.Forms es la mejor opción cuando las aplicaciones requieren menos especificidad en la UI y hacen más énfasis en compartir la mayor cantidad posible de código.

xamarin-1

Xamarin Forms

La capa de abstracción que añade Xamarin Forms a la UI nos facilita la tarea de crear interfaces de usuarios nativas compartidas, ya que cada uno de los elementos de dicha abstracción son mapeados a elementos propios de cada una de las plataformas.

XAML

Las interfaces en Xamarin Forms se pueden definir tanto con código C# desde Code Behind, como con XAML, mi recomendación es utilizar este último para aprovechar su enfoque de separación de responsabilidades entre diseño y codificación.

XAML (eXtensible Application Markup Language) es un lenguaje declarativo basado en XML y pensado para escribir la interfaz gráfica de una aplicación de forma textual y ordenada, aparece por primera vez en la versión 3.0 del Framework de .NET.

Una de las características más importantes de XAML es que todos los elementos que definamos en este son instanciados por el CLR y quedan accesibles como objetos desde código, sin necesidad de realizar de nuevo la declaración de los mismos en Code Behind, gracias al mecanismo de las clases parciales.

XAML permite construir la jerarquía de objetos de componen la interfaz. Con el uso de etiquetaspodemos definir cada uno de los elementos visuales, y con el uso de atributos definimos la apariencia y el comportamiento de cada uno de los elementos.

Veamos un ejemplo de una misma interfaz definida en XAML y C#:

XAML

<TabbedPage.Children>
<ContentPage Title=”Profile” Icon=”Profile.png”>
<StackLayout Spacing=”20″ Padding=”20″ VerticalOptions=”Center”>
<Entry Placeholder=”Username” Text=”{Binding Username}”/>
<Entry Placeholder=”Password” Text=”{Binding Password}” IsPassword=”true”/>
<Button Text=”Login” TextColor=”White” BackgroundColor=”#77D065″ Command=”{Binding LoginCommand}”/>
</StackLayout>
</ContentPage>
<ContentPage Title=”Settings” Icon=”Settings.png”>
<!– Settings –>
</ContentPage>
</TabbedPage.Children>

C#

using Xamarin.Forms;
var profilePage = new ContentPage {
Title = Profile,
Icon = Profile.png,
Content = new StackLayout {
Spacing = 20, Padding = 50,
VerticalOptions = LayoutOptions.Center,
Children = {
new Entry { Placeholder = Username },
new Entry { Placeholder = Password, IsPassword = true },
new Button {
Text = Login,
TextColor = Color.White,
BackgroundColor = Color.FromHex(77D065) }}}
};
var settingsPage = new ContentPage {
Title = Settings,
Icon = Settings.png,
()
};
var mainPage = new TabbedPage { Children = { profilePage, settingsPage } };

Pages

Las páginas son elementos contenedores que representan una pantalla de la aplicación. Xamarin.Forms.Page representa un ViewController en iOS, una Page en UWP, en Android cada página se comporta como un Activity, pero no lo son.
xamarin forms pages
ContentPage: es la página más simple, cuenta con una única vista donde añadir contenido.
MasterDetailPage: gestiona dos paneles de información.
NavigationPage: gestiona la navegación entre paginas.
TabbedPage: facilita el acceso a las subpáginas mediante tabs.
TemplatedPage: muestra el contenido a pantalla completa, permite utilizar plantillas para definir el contenido.
CarouselPage: permite el acceso a las subpáginas haciendo un gesto de scroll lateral.

Layouts

Los layouts son elementos contenedores de otros layouts o vistas, son especialmente necesarios ya que las páginas sólo contener un elemento hijo. Lo utilizaremos para establecer la posición y alineación de los elementos que contienen.
xamarin-forms-layoutsLos más destacados son:
ContentView: permitir crear elementos más complejos a partir del mismo.
ScrollView: si el contenido lo requiere permite hacer scroll.
StackLayout: organiza y posiciona otros controles, es uno de los layouts más utilizados, por defecto los apila verticalmente.
AbsoluteLayout: hace uso posiciones absolutas para posicionar los elementos.
GridLayout: Permite la organización de elementos por medio de filas y columnas.
RelativeLayout: facilita el posicionamiento de los elementos mediante constraints.

Views (controles)

Las Views, también denominados controles o widgets, hacen referencia a los elementos visuales como pueden ser botones, labels, o textboxs. Xamarin Forms nos provee de multiples views:

controls-xamarin
Puedes ver la descripción de cada uno de los controles y como se visualizan en las diferentes plataformas desde aquí.

Creando nuestra primera app Xamarin.Forms

Para crear nuestra app abrimos Visual Studio o Xamarin Studio, dependiendo si estáis en Windows o Mac, respectivamente, en mi caso voy a usar Xamarin Studio. A continuación, nos dirigimos a nueva solución para crear un nuevo proyecto partiendo de la plantilla de aplicación multiplataforma “Forms App”:

app-xamarin-forms-1

En la siguiente pantalla del asistente rellenamos los campos del nombre de la app y del identificador de la organización, seleccionamos las plataformas Android e iOS, en el caso de estar en Visual Studio también podriamos incluir en nuestro proyecto UWP.

Shared Project (SP) vs Portable Class Library (PCL)

Seguidamente nos encontramos con que debemos escoger entre un SP (Shared Project)  y una PCL (Portable Class Library). Aunque ambos persiguen el mismo objetivocompartir la mayor cantidad posible de código entre plataformas, difieren en varios aspectos.

Las PCL a diferencia de los SP, generan un asembly reutilizable (dll) que puede ser consumido fuera de la solución. Es importante tener en cuenta que en las PCL no se tiene acceso completo al framework de .NET.

Los SP no se compilan como un ensamblado a parte, sino como parte de cada proyecto al que están referenciado, como si fuese código del propio proyecto. Los SP permiten hacer uso de directivas que permiten generar código especifico para cada una de las plataformas.

En nuestro caso usaremos la PCL:

app-xamarin-forms-2

Estructura de una solución Xamarin.Forms

Una vez finalizado el asistente, se generará una solución estructurada en tres proyectos:

app-xamarin-forms-3

El primero de los proyectos corresponde a la PCL, el  cual contendrá el código compartido de la aplicación para todas las plataformas. A continuación tenemos los proyectos específicos de iOS y Android.

En el proyecto compartido, a modo de ejemplo se ha generado una página llamada helloFormsPage que cuenta con un elemento de tipo ContentPage que a su vez contiene un control Label en el que se muestra un texto de bienvenida.

HelloFormsPage está formado por dos ficheros por un lado tenemos el XAML y por otro el code behing en C# los cuales corresponden a una misma clase distribuida en dos ficheros, a este concepto se le denomina clases parciales. Por lo tanto el XAML no es más que una clase parcial de nuestro Code Behind, que se completa con el fichero que lleva el  mismo nombre que el XAML pero con la extensión .cs.

<?xml version=“1.0” encoding=“utf-8”?>
<ContentPage xmlns=“http://xamarin.com/schemas/2017/forms”
xmlns:x=“http://schemas.microsoft.com/winfx/2009/xaml”
xmlns:local=“clr-namespace:helloForms”
x:Class=“helloForms.helloFormsPage”>
<Label Text=“Welcome to Xamarin Forms!” VerticalOptions=“Center” HorizontalOptions=“Center” />
</ContentPage>

En el proyecto compartido, además de contar con la clase de ejemplo helloFormsPage, tenemos una clase llamada App, en la cual se indica cual será la primera página a mostrar en todas las plataformas, esto se realiza en el constructor de la misma. Además cuenta con otros métodos que nos permiten ejecutar acciones según el estado de la aplicación.

namespace helloForms
{
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new helloFormsPage();
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
}

 

En el proyecto de Android tenemos una clase denominada MainActivity que cuenta con un método OnCreate() en el cual inicializamos la app del proyecto compartido:

namespace helloForms.Droid
{
[Activity(Label = helloForms.Droid, Icon = @drawable/icon, Theme = @style/MyTheme, MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
}
}

 

Por último, en iOS, disponemos de la clase AppDelegate en la cual cargaremos la app del proyecto compartido:

namespace helloForms.iOS
{
[Register(AppDelegate)]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
}
}

 

Si, ejecutamos el proyecto en los emuladores de iOS y Android obtendríamos el siguiente resultado:

app-xamarin-forms-4

El patrón MVVM en Xamarin Forms

Aunque no es obligatorio utilizar el patrón MVVM para desarrollar una aplicación con Xamarin Forms, está considerado una buena práctica hacer uso del mismo. A continuación veremos algunos conceptos claves para entender el por qué.

MVVM (Modelo Vista Vista-Modelo) es un patrón de diseño derivado de MVC, cuyo objetivo es tratar de desacoplar al máximo la interfaz de usuario de la lógica de la aplicación,  para ello hace uso de un lenguaje de marcado en las vistas, XAML en el caso de Xamarin Forms. El modelo realiza la misma función que en MVC, representa la capa de datos y/o la lógica de negocio de nuestro proyecto, en ningún caso tiene dependencia alguna de la vista.

El ViewModel (modelo de vista) es un actor intermediario entre el modelo y la vista, contiene toda la lógica de presentación y se comporta como una abstracción de la interfaz. La comunicación entre la vista y el viewmodel se realiza por medio los enlaces de datos (binders).

mvvm-1

A continuación vamos a crear un ejemplo sencillo para mostrar como implementar en una solución Xamarin forms el patrón MVVM.

Vamos a partir de un nuevo proyecto Xamarin.Forms utilizando una librería portable. En la PCL creamos las carpetas Views, ViewModels, y dentro de ViewModels la carpeta Base. Quedando la estructura de la solución tal que así:

mvvm-2

Una vez creadas las carpetas, añadimos la página principal, para ello hacemos clic derecho sobre la carpeta Views, le damos a la opción agregar nuevo archivo, seleccionamos “Forms ContentPage”,  lo llamamos MainView y añadimos el siguiente código:

<?xml version=“1.0” encoding=“utf-8” ?>
<ContentPage xmlns=“http://xamarin.com/schemas/2017/forms”
xmlns:x=“http://schemas.microsoft.com/winfx/2009/xaml”
x:Class=“simpleMVVM.Views.MainView”>
<Label Text=“{Binding MyMessage}”
VerticalOptions=“Center”
HorizontalOptions=“Center” />
</ContentPage>

En el XAML anterior podemos observar que en el atributo text  del elemento Label hemos utilizado lo que se denomina una expresión de enlace a datos, en próximos posts veremos con más detalle su funcionamiento por ahora nos basta con saber que cuando el compilador se encuentra con una expresión entre llaves la interpreta,y, en este caso, al encontrarse con la palabra reservada Binding, lo que hace es enlazar el valor de la propiedad MyMessage la cual definiremos en el ViewModel.

Lo siguiente que vamos a hacer es crear nuestro primer ViewModel. Un ViewModel no es más que una clase en la que se expone la información con propiedades públicas. Por lo tanto, agregamos dentro de la carpeta ViewModels una clase a la que vamos a denominar MainViewModel con una propiedad llamada “MyMessage”:

public class MainViewModel
{
private string _myMessage;
public MainViewModel()
{
Message = Hello MVVM!;
}
public string MyMessage
{
get { return _myMessage; }
set { _myMessage = value; }
}
}

A continuación, tenemos que enlazar nuestro ViewModel con el contexto de datos de la página. Para ello asignamos en la propiedad BindingContext de la nuestra vista una instancia de nuestro ViewModel. El Code Behind de la vista quedaría así:

namespace simpleMVVM.Views
{
public partial class MainView : ContentPage
{
public MainView()
{
InitializeComponent();
BindingContext = new MainViewModel();
}
}
}

Por último, tan solo nos queda indicar cual es la página principal en la propiedad MainPage de la clase App:

public App()
{
InitializeComponent();
MainPage = new MainView();
}

Esta sería la estructura MVVM más sencilla posible, en principio nos sirve para ilustrar los fundamentos básicos. No obstante, no hemos cubierto  conceptos como los modos de enlace a datoslas notificaciones y los comandos, imprescindibles para conseguir una de interacción completa del usuario, quedarán pendientes para próximas entradas.

Resumen

En este artículo he tratado de sentar las bases, en la medida de lo posible, de Xamarin y en particular de Xamarin Forms, me he dejado muchos temas en el tintero, y en otros he sido muy superficial, cómo por ejemplo en la introducción del patrón MVVM, pero el post estaba creciendo exponencialmente.

La idea es continuar profundizando en próximas entradas en el desarrollo con Xamarin, tanto tradicional como con forms. Espero haber facilitado tu transición a Xamarin, o por lo menos haber sabido trasladarte alguna de sus virtudes.