Seleccionar página
19 de septiembre de 2023

MAUI y Blazor: la combinación perfecta para el desarrollo de aplicaciones multiplataforma

Con el avance de la tecnología móvil, ha surgido .NET MAUI, una plataforma de desarrollo multiplataforma que promete simplificar la creación de aplicaciones para dispositivos móviles. En este blog, explicaremos cómo MAUI se combina con Blazor, la tecnología de Microsoft para aplicaciones web modernas, ofreciendo una experiencia de desarrollo unificada y eficiente en todas las plataformas.

.NET MAUI es un framework de desarrollo de aplicaciones multiplataforma de código abierto desarrollado por Microsoft. Se lanzó como una evolución de Xamarin.Forms, con el objetivo de simplificar aún más el desarrollo de aplicaciones móviles y ofrecer una experiencia unificada en diferentes sistemas operativos y dispositivos. Ofrece los siguientes beneficios clave: 

 

  • Un solo código base: Se puede escribir una única base de código que se comparte entre las plataformas, reduciendo el tiempo de crear la aplicación y simplifica la gestión del código.
  • Interfaz de usuario adaptable: MAUI ofrece un sistema de diseño adaptable que permite crear interfaces de usuario que se ajustan automáticamente a las diferencias en las pantallas y los factores de forma de diferentes dispositivos.
  • Acceso nativo: Los desarrolladores pueden acceder a las APIs nativas de cada plataforma cuando sea necesario, lo que significa que pueden aprovechar las características específicas de iOS, Android u otras plataformas.
  • Soporte para múltiples plataformas: Además de dispositivos móviles, .NET MAUI permite desarrollar aplicaciones de escritorio para Windows y macOS, lo que amplía su versatilidad.

¿Qué es BLAZOR?

Blazor es un framework de desarrollo web también desarrollado por Microsoft. Lo que lo hace único es su capacidad para permitir a los desarrolladores crear aplicaciones web interactivas y dinámicas utilizando C# y .NET en lugar de JavaScript. Ofrece los siguientes beneficios clave:

 

  • Lenguaje unificado: Habilita a los desarrolladores para escribir la lógica tanto del cliente como del servidor en el mismo lenguaje, lo que simplifica el desarrollo y mejora la coherencia en la aplicación.
  • Componentes reutilizables: Blazor se basa en el concepto de componentes, que son unidades de interfaz de usuario reutilizables. Los componentes pueden encapsular la lógica y la presentación, lo que facilita la creación y el mantenimiento de interfaces de usuario complejas.
  • Interacción en tiempo real: Blazor Server permite una interacción en tiempo real con la aplicación mediante SignalR. Esto implica que cualquier cambio realizado en la aplicación se refleja instantáneamente en todos los clientes conectados, sin necesidad de recargar la página.
  • Blazor WebAssembly: Permite ejecutar aplicaciones Blazor directamente en los navegadores, ofreciendo una experiencia de usuario similar a las aplicaciones de una sola página (SPA) sin necesidad de un servidor. Esto permite que las aplicaciones sean más rápidas.

¿Por qué integrar MAUI y Blazor? 

Después de hacer un pequeño análisis de los dos frameworks de Microsoft y de sus ventajas, vamos a exponer cómo podríamos potenciar el desarrollo de nuestro proyecto al integrarlos de manera conjunta.

.NET MAUI se integra perfectamente con Blazor, permitiéndonos compartir una gran parte del código y de la lógica empresarial entre las aplicaciones móviles y web. Lo que nos lleva a un ahorro de tiempo y esfuerzo en el desarrollo.

Uno de los aspectos más destacados de .NET MAUI es su capacidad para ejecutar los componentes de Blazor de manera nativa en el dispositivo, sin necesidad de Web Assembly, y los muestra en un control de vista web integrado. Esto significa que los componentes de Blazor pueden aprovechar todas las características nativas de la plataforma, tales como Bluetooth, geolocalización, sensores, acelerómetro y estados de la batería entre otras. 

La integración de MAUI con Blazor proporciona a los desarrolladores la capacidad de crear aplicaciones multiplataforma que combinan la potencia y la flexibilidad del lenguaje C# con la interfaz de usuario nativa de cada plataforma, ofreciendo así una solución altamente eficaz y versátil.

Aplicación híbrida .NET MAUI Blazor 

Hemos realizado una demostración práctica que ilustra la integración entre .NET MAUI y Blazor. El conjunto se compone de tres partes: un proyecto de aplicación híbrida .NET MAUI Blazor, un proyecto de aplicación Blazor normal, y una librería compartida en Blazor que alberga el código compartido. El objetivo de esta propuesta es centralizar, en la medida de lo posible, la capa de presentación y la lógica de negocio dentro de la librería Blazor. Esta librería se centra en implementar el código común destinado a representar las vistas y la lógica subyacente. Con esta estructura, los proyectos MAUI y Blazor se limitan principalmente a ejecutar la aplicación, conectándose con el código común, y añadiendo las funcionalidades específicas de cada plataforma cuando sea necesario.

Por tanto, los Program de cada proyecto de aplicación se encargarán de mostrar su vista principal enlazada con el proyecto compartido de Blazor. El proyecto de web Blazor lo enlaza desde su Program.cs donde vemos que hace referencia al proyecto Lib, el cual contiene todo el contenido de la App que luego se usa en las distintas plataformas, y el proyecto en MAUI lo enlaza desde su Main.razor, donde vemos que hace referencia al proyecto Lib también.

Program.cs 

var builder = WebAssemblyHostBuilder.CreateDefault(args); 

builder.RootComponents.Add<MultiplatformDemo.Lib.App>(«#app»); 

builder.RootComponents.Add<HeadOutlet>(«head::after»); 

 

Main.razor 

<Router AppAssembly@typeof(Main).Assembly« AdditionalAssemblies=»new[] { typeof(MultiplatformDemo.Lib.MainLayout).Assembly }« PreferExactMatches=»true»> 

    <Found Context=»routeData»> 

        <RouteView RouteData@routeData« DefaultLayout@typeof(MainLayout)» /> 

        <FocusOnNavigate RouteData@routeData« Selector=»h1″ /> 

    </Found> 

    <NotFound> 

        <LayoutView Layout@typeof(MainLayout)«> 

            <p role=»alert»>Sorry, there’s nothing at this address.</p> 

        </LayoutView> 

    </NotFound> 

</Router> 

Además de enlazar con el código compartido, los proyectos específicos de cada plataforma también deben gestionar la implementación de servicios de infraestructura exclusivos de dicha plataforma. Un ejemplo claro es el servicio de geolocalización. El acceso al sensor de geolocalización del dispositivo y la gestión de los permisos necesarios requieren código específico de cada plataforma. Para ello, la interfaz se declara en el código común y sus implementaciones concretas se sitúan en los respectivos proyectos de aplicación. De esta forma, usando inyección de dependencias, el proyecto compartido podrá utilizar la implementación adecuada del servicio.

Esta es la interfaz que tenemos definida en el código compartido:

namespace MultiplatformDemo.Lib.Data 

{ 

    public interface IGeolocationService 

    { 

        public event EventHandler<Position> PositionObtained; 

        public Task GetLocationAsync(); 

    } 

} 

La interfaz define un método asíncrono para poder lanzar la petición de geolocalización y un evento que se invocará cuando se haya obtenido esta información.

En el proyecto de aplicación Blazor utilizamos javascript para invocar la petición de geolocalización en el navegador.

public async Task GetLocationAsync() 

        { 

            try 

            { 

                await jsRuntime.InvokeVoidAsync(«getCurrentPosition», new object[3] { DotNetObjectReference.Create(this), nameof(OnPositionReceived), nameof(OnPositionError) }); 

            } 

            catch (Exception ex) 

            { 

                Console.WriteLine(ex.Message); 

            } 

        } 

 

        [JSInvokable] 

        public void OnPositionReceived(Position position) 

        { 

            PositionObtained?.Invoke(this, position); 

        } 

Para el proyecto de MAUI utilizamos una librería oficial de Microsoft.MAUI para obtener la Geolocalización. Esta librería es accesible para todas las implementaciones de MAUI (android, ios, windows, etc) por lo que no será necesario crear un servicio específico para cada plataforma distinta dentro de MAUI.

  public async Task GetLocationAsync() 

        { 

            try 

            { 

 

                PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>(); 

                if (status != PermissionStatus.Granted) 

                { 

                    status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>(); 

 

                    if (status != PermissionStatus.Granted) 

                    { 

                        return; 

                    } 

                } 

                Location location = await Geolocation.Default.GetLocationAsync(); 

 

                if (location != null) 

                    PositionObtained.Invoke(this, new Position { Coords =  new Coordinates { Latitude = location.Latitude, Longitude = location.Longitude } }); 

            } 

            catch (Exception ex) 

            { 

                // Unable to get location 

            } 

        } 

 

Por último, en los Program.cs de cada proyecto de aplicación añadiremos el servicio a la inyección de dependencias con la instrucción

“builder.Services.AddScoped<IGeolocationService, GeolocationService>();”.

De esta forma en el código común podemos hacer uso de la geolocalización, y seguidamente utilizar un servicio de dominio que se encargue de obtener los datos del tiempo a través de la información obtenida y mostrar los resultados en una vista.

En este código podemos ver como el código compartido recibe por inyección de dependencias el servicio y lo utiliza para obtener la geolocalización.

[Inject] 

        private IGeolocationService GeolocationService { get; set; } 

 

        private Position Position; 

 

        protected override async Task OnInitializedAsync() 

        { 

            GeolocationService.PositionObtained += PositionObtained; 

            await GeolocationService.GetLocationAsync(); 

            await base.OnInitializedAsync(); 

        } 

 

        private void PositionObtained(object sender, Position p) 

        { 

            Position = p; 

            StateHasChanged(); 

        } 

Más tarde en la vista del tiempo, utilizará esta información para obtener información del tiempo a través de un servicio de dominio del código compartido.

  protected override async Task OnAfterRenderAsync(bool firstRender) 

        { 

            if (firstRender) 

            { 

                weatherData = await weatherService.GetWeatherAsync(Latitude, Longitude); 

                StateHasChanged(); 

            } 

            await base.OnAfterRenderAsync(firstRender); 

        } 

Por tanto, podemos desarrollar todas las vistas y lógica de una aplicación en el código común, obteniendo un código centralizado para diferentes plataformas de forma muy fácil, y cuando sea necesario recurrir a la inyección por dependencias para obtener la implementación de un determinado servicio que utiliza código específico de la plataforma donde se está ejecutando. 

Para crear la aplicación híbrida .NET MAUI Blazor hemos seguido la documentación oficial de Microsoft:

https://learn.microsoft.com/en-us/aspnet/core/blazor/hybrid/tutorials/maui?view=aspnetcore-7.0

¿Por qué .net maui y blazor?

.NET MAUI y Blazor son dos tecnologías líderes en el desarrollo multiplataforma. La integración de ambas proporciona una solución poderosa y eficiente para la creación de aplicaciones que funcionan en una variedad de dispositivos y plataformas. Esta combinación ofrece una experiencia de desarrollo unificada, reduciendo tanto el tiempo como los costos asociados con el desarrollo y mantenimiento de aplicaciones multiplataforma. 

En resumen, en un mundo cada vez más enfocado en la movilidad y la accesibilidad, es importante poder llegar a una audiencia más amplia, y la colaboración entre .NET MAUI y Blazor simplifica significativamente este proceso.

Artículo escrito por Sandra Carreras Masanet, Specialist Developer en Verne Tech.

[dgbm_blog_module posts_number=»3″ related_posts=»on» title_tag=»h3″ show_categories=»off» meta_date=»d/m/y» show_pagination=»off» show_more=»on» read_more_text=»Leer más» space_between=»50px» equal_height=»on» button_alignment=»right» button_at_bottom=»on» container_padding=»||||false|false» image_margin=»||25px||false|false» content_padding=»|25px||25px|false|true» title_margin=»||15px||false|false» text_margin=»||50px||false|false» button_wrapper_margin=»||||false|false» button_margin=»40px|50px|25px||false|false» author_location=»bottom» date_location=»bottom» _builder_version=»4.22.1″ _module_preset=»default» title_font=»Roboto||||||||» title_font_size=»25px» meta_text_color=»#353432″ read_more_font=»Roboto|700|||||||» read_more_text_color=»#353432″ read_more_font_size=»13px» pagination_text_color=»#353432″ pagination_font_size=»16px» author_font_size=»13px» date_font_size=»13px» border_width_bottom_image=»5px» border_color_bottom_image=»#3686C7″ global_colors_info=»{}»][/dgbm_blog_module]