Elbrinner da Silva Fernandes

Blog sobre Xamarin, MVVMCROSS y UWP (Plataforma universal de Windows)

Crear un proyecto con Xamarin Classic usando PCL y MvvmCross

Crear un proyecto con Xamarin Classic usando PCL y MvvmCross

Cuando se empieza a desarrollar con Xamarin y buscamos tutoriales por internet, vemos una serie de patrones de diseño, buenas prácticas y siglas que dar algo de respecto cuando no lo conocemos, como puede ser MVVM, inyección de dependencias, contenedores IOC, converters, command, binding, custom presenter y etc…

La parte buena es que de forma inicial existen frameworks como MvvmCross, que ofrecen toda la arquitectura inicial para empezar sin tener que conocer cada pieza al detalle desde el principio.

Para crear nuestro proyecto “Base” con MvvmCross desde 0, hay que seguir los siguientes pasos.

Paso 1: Crear una solución vacía. Está solución será el contenedor principal de todos los proyectos que vamos agregar.

Nueva solución

Paso 2: Agregar un proyecto para la lógica de negocio, un proyecto de tipo PCL. Para agregar tenemos que hacer clic con el segundo botón sobre el nombre de la solución vacía, al hacer clic con el segundo botón se abre un menú de opciones y debemos elegir agregar y luego nuevo proyecto.

 

Ahora tenemos que seleccionar el tipo de proyecto que queremos. En nuestro caso queremos un proyecto de tipo C# que sea una librería de clase portable, lo vamos a llamar de Base.Core. Base porque es el nombre de nuestra solución y Core porque se trata del proyecto que va a contener la lógica de negocio, nomenclatura usada de forma extendida dentro de las comunidades de desarrolladores.

Seleccionar una PCL

Paso 3: Elegir el perfilado de la PCL, seleccionamos los tipos de proyectos en que queremos compartir la lógica de negocio, en nuestro caso necesitamos para IOS, Android y UWP.

 

Haga clic en aceptar y se creará el proyecto. Elimine el archivo Class1.cs que no vamos a necesitar.

 

Paso 4: Crear todos los proyectos de plataforma, Android, UWP y IOS. El proceso es similar al anterior, pero en lugar de crear un proyector de tipo PCL, vamos a crear un de tipo plataforma.

Para Android

Para IOS

Para UWP - Windows

Seleccionamos la versión de destino de la aplicación y la versión mínima que soportará la aplicación.

Paso 5: La principal ventaja de Xamarin es la reutilización, como toda nuestra lógica de negocio está en el proyecto Base.Core, lo vamos referéncialo en todos los proyectos de plataforma. Para referenciar haga clic con el segundo botón sobre referencias y seleccione la opción agregar referencia del menú. Haga clic sobre solución y elija el proyecto de tipo PCL (Base.Core) y haga clic en aceptar.

El resultado es la librería Base.Core dentro de las referencias.

 

Paso 6: Agregar la librería de MvvmCross desde nuget, existe una versión que agiliza la configuración del proyecto. Haga clic con el segundo botón sobre la solución Base y seleccione la opción administrar paquetes nuget para la solución y busque por Mvvmcross starter.

 

 

Seleccione todos los proyectos y haga clic en instalar. Se va abrir una ventana que indica todo que se va instalar en cada uno de los proyectos, haga clic en aceptar para empezar la instalación, este proceso puede tardar unos segundos.

 

Paso 7: Comprobar la configuración del proyecto de Base.Core.

Podemos comprobar que al instalar el paquete de nuget de MvvmCross se agregó algunos archivos en el proyecto.

Un archivo MainViewModel.cs con la lógica de negocio “Hola Mundo” , que contiene una propiedad pública que se usará en la vista de la plataforma y un ICommand que llamar a una función que volver a reiniciar el valor de la propiedad pública.

 

La clase App.cs proporciona la inicialización para su lógica de negocio principal y sus modelos de vista.

La línea que esta destacada en el código, será la vista principal a cargar, en este caso cargará la vista MainView, esta vista está asociado al viewmodel MainViewModel.

 

Para configurar la base del proyecto “Hola Mundo” no tenemos que hacer nada más en este proyecto.

Paso 8: Configurar proyecto Android. MvvmCross facilita la configuración, tenemos que hacer 2 cosas, agregar la referencia del proyecto Core que ya hicimos en los pasos anteriores y eliminar el archivo MainActivity.cs, en su lugar Mvvmcross vamos a trabajar con las vistas que hereda de MvxActivity.

Una vez eliminado el archivo MainActivity.cs ejecutamos la solución en el simulador de Android o en un terminal. En mi caso voy a ejecutar en un Samsung SM, solo tenemos que hacer clic sobre el botón.

Ha ocurrido un error en la compilación, hay un recurso que no se está encontrando.

Abra el fichero SplashScreen.cs y modifique la siguiente línea:

, Icon = "@mipmap/icon"

Por esta:

, Icon = "@drawable/icon"

Revise si la carpeta drawable contiene una imagen con el nombre icon.png (Icono principal que se muestra en el teléfono para abrir la aplicación). Caso no exista, es necesario crearla o ocurrirá un error al arrancar la aplicación.

 

Vuelva a compilar la aplicación. Ahora todo debería funcionar de forma correcta, debería ver una pantalla negra con un texto “Hello MvvmCross” con un botón de reset.

Antes de empezar a crear su aplicación, elimine la carpeta ToDo-MvvmCross.

 

Paso 9: Configurar proyecto IOS. Tenemos que hacer la referencia del proyecto de Core que ya hicimos en los pasos anteriores y modificar el archivo AppDelegate.cs , los nuevos valores a aplicar están en el archivo AppDelegate.cs.txt

AppDelegate ahora debe heredar de MvxApplicationDelegate.

Debemos cambiar:

public class AppDelegate : UIApplicationDelegate

Por:

public partial class AppDelegate : MvxApplicationDelegate

También es necesario modificar la función FinishedLaunching.

Debemos cambiar:

public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
{
     // Override point for customization after application launch.
	// If not required for your application you can safely delete this method

return true;
}

Por:

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

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

            var startup = Mvx.Resolve();
            startup.Start();

            Window.MakeKeyAndVisible();

            return true;
}

 

El último paso es agregar las referencias de MvvmCross.

using MvvmCross.Core.ViewModels;
using MvvmCross.iOS.Platform;
using MvvmCross.Platform;

Ya estamos listo para probar, recuerde que vamos a necesitar de un Mac para compilar.

 

En la versión que estoy probando, se ha producido un error en el fichero Setup.cs

Abrimos el fichero Setup.cs y aplicamos los siguientes cambios.

Cambiar:

public Setup(IMvxApplicationDelegate applicationDelegate, UIWindow window, IMvxIosViewPresenter presenter)
            : base(applicationDelegate, window, presenter)
        {
        }

Por:

public Setup(IMvxApplicationDelegate applicationDelegate, IMvxIosViewPresenter presenter)
            : base(applicationDelegate, presenter)
        {
        }

 

Ahora debería funcionar. Elimine la carpeta ToDo-MvvmCross y ya puedes empezar tu aplicación para IOS.

 

Paso 10:  Configurar proyecto para UWP. Para la configuración para UWP MvvmCross no genera ningún tipo de archivo, así que tenemos que hacer todo el trabajo de forma manual.

Lo primero que tenemos que hacer es agregar la referencia del proyecto de Core, que ya hicimos en los pasos anteriores.

Tenemos que crear una carpeta para las vistas, hacemos clic con el segundo botón sobre el proyecto de Base.UWP y elegimos la opción agregar, y luego clicamos en la opción nueva carpeta, llamaremos la nueva carpeta de Views.

Ahora hacemos clic sobre la carpeta Views con el segundo botón, elegiremos la opción de agregar y luego la opción de nuevo elemento. Va abrir una ventana que verás en la imagen abajo, debemos crear una página en blanco con el nombre de MainView.

Antes de empezar a trabajar con la vista nueva, vamos a eliminar el archivo MainPage.xaml del proyecto que no lo necesitamos al usar MvvmCross.

Abrimos el archivo MainView.xaml.cs , quitamos la herencia de Page y agregamos la de MvxWindowsPage, el resultado será el siguiente.

public sealed partial class MainView : MvxWindowsPage { 
  public MainView() { 
     this.InitializeComponent();
  } 
} 

 

Tenemos que hacer lo mismo con el código Xaml, cambiar page por views:MvxWindowsPage y agregar la referencia.

 

xmlns:views="using:MvvmCross.Uwp.Views"

 

El resultado será este:


 

Vamos a crear el archivo Setup.cs en la raíz del proyecto de Base.UWP, hacemos clic sobre la solución, elegimos la opción agregar y luego la opción nuevo elemento. Se va abrir una ventana que podemos elegir el tipo de archivo y el nombre, seleccionamos de tipo clase y con el nombre Setup.cs

 

 

El código que va a contener este archivo es el siguiente:

 

using MvvmCross.Core.ViewModels;
using MvvmCross.Platform.Plugins;
using MvvmCross.Uwp.Platform;
using Windows.UI.Xaml.Controls;

namespace Base.UWP
{
    public class Setup : MvxWindowsSetup
    {
        public Setup(Frame rootFrame) : base(rootFrame)
        {
        }

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

        protected override IMvxPluginManager CreatePluginManager()
        {
            return base.CreatePluginManager();
        }

        protected override void InitializeFirstChance()
        {

        }
    }
}

 

El siguiente paso es abrir el archivo App.Xaml.cs y remplazar la función OnLaunched por esta:

protected override void OnLaunched(LaunchActivatedEventArgs e)
        {
            Frame rootFrame = Window.Current.Content as Frame;

            // No repetir la inicialización de la aplicación si la ventana tiene contenido todavía,
            // solo asegurarse de que la ventana está activa.
            if (rootFrame == null)
            {
                
                rootFrame = new Frame();

                rootFrame.NavigationFailed += OnNavigationFailed;

                if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    
                }
              
                Window.Current.Content = rootFrame;
            }



            if (rootFrame.Content == null)
            {
                //rootFrame.Navigate(typeof(MainPage), e.Arguments);
                var setup = new Setup(rootFrame);
                setup.Initialize();

                var start = Mvx.Resolve();
                start.Start();
            }
            
            Window.Current.Activate();
        }
}

 

Debemos agregar las referencias que faltan, que son:

using MvvmCross.Core.ViewModels;
using MvvmCross.Platform;

 

Establecemos el Proyecto de Base.UWP como proyecto de inicio y le damos la opción de implementar la solución, con esto debemos ver una pantalla en blanco y la configuración ya está completada. Para igualar la pantalla, vamos modificar nuestra vista para agregar 2 campos para que muestren lo mismo que en los proyectos de IOS y Android.

 

Se puedes descagar el ejemplo completo en github

 

 

Elbrinner da Silva Fernandes Elbrinner da Silva Fernandes
Consultor Xamarin, experto en mobilidad en everis España.
Madrid Spain

Xamarin Certificado

Xamarin Master

Certificación Solutions developer App Builder

Certicación Solutions Associate Web applications

Microsoft Active Professional

Microsoft Professional

Specialist programaming in C#

Specialist programaming in HTML5 with JavaScript & CSS3

Planet Xamarin