Invocar código de plataforma

Examinar ejemplo. Examinar el ejemplo

En situaciones en las que la interfaz de usuario de aplicación multiplataforma de .NET (.NET MAUI) no proporciona ninguna API para acceder a api de plataforma específicas, puede escribir su propio código para acceder a las API de plataforma necesarias. Esto requiere conocimientos de las API de iOS y MacCatalyst de Apple, las API de Android de Google y las API de SDK de Aplicaciones para Windows de Microsoft.

El código de plataforma se puede invocar desde código multiplataforma mediante la compilación condicional o mediante clases parciales y métodos parciales.

Compilación condicional

El código de plataforma se puede invocar desde código multiplataforma mediante la compilación condicional para tener como destino distintas plataformas.

En el ejemplo siguiente se muestra la DeviceOrientation enumeración , que se usará para especificar la orientación del dispositivo:

namespace InvokePlatformCodeDemos.Services
{
    public enum DeviceOrientation
    {
        Undefined,
        Landscape,
        Portrait
    }
}

Recuperar la orientación del dispositivo requiere escribir código de plataforma. Esto se puede lograr escribiendo un método que usa la compilación condicional para tener como destino distintas plataformas:

#if ANDROID
using Android.Content;
using Android.Views;
using Android.Runtime;
#elif IOS
using UIKit;
#endif

using InvokePlatformCodeDemos.Services;

namespace InvokePlatformCodeDemos.Services.ConditionalCompilation
{
    public class DeviceOrientationService
    {
        public DeviceOrientation GetOrientation()
        {
#if ANDROID
            IWindowManager windowManager = Android.App.Application.Context.GetSystemService(Context.WindowService).JavaCast<IWindowManager>();
            SurfaceOrientation orientation = windowManager.DefaultDisplay.Rotation;
            bool isLandscape = orientation == SurfaceOrientation.Rotation90 || orientation == SurfaceOrientation.Rotation270;
            return isLandscape ? DeviceOrientation.Landscape : DeviceOrientation.Portrait;
#elif IOS
            UIInterfaceOrientation orientation = UIApplication.SharedApplication.StatusBarOrientation;
            bool isPortrait = orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown;
            return isPortrait ? DeviceOrientation.Portrait : DeviceOrientation.Landscape;
#else
            return DeviceOrientation.Undefined;
#endif
        }
    }
}

En este ejemplo, se proporcionan implementaciones de plataforma del GetOrientation método para Android e iOS. En otras plataformas, DeviceOrientation.Undefined se devuelve . Como alternativa, en lugar de devolver DeviceOrientation.Undefined , podría producir un PlatformNotSupportedException que especifique las plataformas para las que se proporcionan implementaciones:

throw new PlatformNotSupportedException("GetOrientation is only supported on Android and iOS.");

A DeviceOrientationService.GetOrientation continuación, el método se puede invocar desde código multiplataforma mediante la creación de una instancia de objeto y la invocación de su operación:

using InvokePlatformCodeDemos.Services;
using InvokePlatformCodeDemos.Services.ConditionalCompilation;
...

DeviceOrientationService deviceOrientationService = new DeviceOrientationService();
DeviceOrientation orientation = deviceOrientationService.GetOrientation();

En tiempo de compilación, el sistema de compilación usa la compilación condicional para dirigirse al código de la plataforma Android e iOS a la plataforma correcta.

Para obtener más información sobre la compilación condicional, vea Compilación condicional.

Clases y métodos parciales

Un proyecto de aplicación MAUI de .NET contiene una carpeta Platforms , con cada carpeta secundaria que representa una plataforma que .NET MAUI puede tener como destino:

Captura de pantalla de carpetas de plataforma.

Las carpetas de cada plataforma de destino contienen código específico de la plataforma que inicia la aplicación en cada plataforma, además de cualquier código de plataforma adicional que agregue. En tiempo de compilación, el sistema de compilación solo incluye el código de cada carpeta al compilar para esa plataforma específica. Por ejemplo, al compilar para Android, los archivos de la carpeta Plataformas>Android se integrarán en el paquete de la aplicación, pero los archivos de las demás carpetas Plataformas no serán. Este enfoque usa una característica denominada multi-targeting para tener como destino varias plataformas desde un único proyecto.

El destino múltiple se puede combinar con clases parciales y métodos parciales para invocar la funcionalidad de la plataforma desde código multiplataforma. El proceso para hacerlo es:

  1. Defina la API multiplataforma como una clase parcial que defina firmas de método parciales para las operaciones que quiera invocar en cada plataforma. Para más información, consulte Definición de la API multiplataforma.
  2. Implemente la API multiplataforma por plataforma mediante la definición de la misma clase parcial y las mismas firmas de método parcial, al tiempo que proporciona las implementaciones del método. Para más información, consulte Implementación de la API por plataforma.
  3. Invoque la API multiplataforma mediante la creación de una instancia de la clase parcial y la invocación de sus métodos según sea necesario. Para obtener más información, consulte Invocación de la API multiplataforma.

Definición de la API multiplataforma

Para invocar código de plataforma desde código multiplataforma, el primer paso es definir la API multiplataforma como una clase parcial que define firmas de método parciales para las operaciones que quiera invocar en cada plataforma.

En el ejemplo siguiente se muestra la DeviceOrientation enumeración , que se usará para especificar la orientación del dispositivo:

namespace InvokePlatformCodeDemos.Services
{
    public enum DeviceOrientation
    {
        Undefined,
        Landscape,
        Portrait
    }
}

En el ejemplo siguiente se muestra una API multiplataforma que se puede usar para recuperar la orientación de un dispositivo:

namespace InvokePlatformCodeDemos.Services.PartialMethods
{
    public partial class DeviceOrientationService
    {
        public partial DeviceOrientation GetOrientation();
    }
}

La clase parcial se denomina DeviceOrientationService, que incluye un método parcial denominado GetOrientation. El archivo de código de esta clase debe estar fuera de la carpeta Platforms :

Clase DeviceOrientationService en la captura de pantalla de la carpeta Services.

Implementación de la API por plataforma

Después de definir la API multiplataforma, debe implementarse en todas las plataformas destinadas mediante la definición de la misma clase parcial y las mismas firmas de método parcial, al tiempo que se proporcionan las implementaciones del método.

Las implementaciones de plataforma deben colocarse en las carpetas secundarias Plataformas correctas para asegurarse de que el sistema de compilación solo intenta compilar código de plataforma al compilar para la plataforma específica. En la tabla siguiente se enumeran las ubicaciones de carpetas predeterminadas para las implementaciones de la plataforma:

Plataforma Carpeta
Android Plataformas>Android
iOS Plataformas>Ios
MacCatalyst Plataformas>MacCatalyst
Tizen Plataformas>Tizen
Windows Plataformas>Windows

Importante

Las implementaciones de plataforma deben estar en el mismo espacio de nombres y en la misma clase en la que se definió la API multiplataforma.

En la captura de pantalla siguiente se muestran las DeviceOrientationService clases de las carpetas Android e iOS :

Captura de pantalla de las clases DeviceOrientationService en su carpeta Platforms.

Como alternativa, se pueden realizar varios destinos en función de sus propios criterios de nombre de archivo y carpeta, en lugar de usar las carpetas Plataformas . Para obtener más información, consulte Configuración de varios destinos.

Android

En el ejemplo siguiente se muestra la implementación del GetOrientation método en Android:

using Android.Content;
using Android.Runtime;
using Android.Views;

namespace InvokePlatformCodeDemos.Services.PartialMethods;

public partial class DeviceOrientationService
{
    public partial DeviceOrientation GetOrientation()
    {
        IWindowManager windowManager = Android.App.Application.Context.GetSystemService(Context.WindowService).JavaCast<IWindowManager>();
        SurfaceOrientation orientation = windowManager.DefaultDisplay.Rotation;
        bool isLandscape = orientation == SurfaceOrientation.Rotation90 || orientation == SurfaceOrientation.Rotation270;
        return isLandscape ? DeviceOrientation.Landscape : DeviceOrientation.Portrait;
    }
}

iOS

En el ejemplo siguiente se muestra la implementación del GetOrientation método en iOS:

using UIKit;

namespace InvokePlatformCodeDemos.Services.PartialMethods;

public partial class DeviceOrientationService
{
    public partial DeviceOrientation GetOrientation()
    {
        UIInterfaceOrientation orientation = UIApplication.SharedApplication.StatusBarOrientation;
        bool isPortrait = orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown;
        return isPortrait ? DeviceOrientation.Portrait : DeviceOrientation.Landscape;
    }
}

Invocación de la API multiplataforma

Después de proporcionar las implementaciones de la plataforma, la API se puede invocar desde código multiplataforma mediante la creación de una instancia de objeto y la invocación de su operación:

using InvokePlatformCodeDemos.Services;
using InvokePlatformCodeDemos.Services.PartialMethods;
...

DeviceOrientationService deviceOrientationService = new DeviceOrientationService();
DeviceOrientation orientation = deviceOrientationService.GetOrientation();

En tiempo de compilación, el sistema de compilación usará varios destinos para combinar la clase parcial multiplataforma con la clase parcial para la plataforma de destino y compilarla en el paquete de la aplicación.

Configuración de varios destinos

Las aplicaciones .NET MAUI también pueden ser de destino múltiple en función de sus propios criterios de nombre de archivo y carpeta. Esto le permite estructurar el proyecto de aplicación MAUI de .NET para que no tenga que colocar el código de la plataforma en carpetas secundarias de la carpeta Plataformas .

Por ejemplo, un patrón estándar de múltiples destinos consiste en incluir la plataforma como una extensión en el nombre de archivo del código de la plataforma. El sistema de compilación se puede configurar para combinar clases parciales multiplataforma con clases parciales de plataforma basadas en este patrón:

Clases DeviceOrientationService que usan el destino múltiple basado en nombre de archivo.

Otro patrón estándar de varios destinos es incluir la plataforma como un nombre de carpeta. El sistema de compilación se puede configurar para combinar clases parciales multiplataforma con clases parciales de plataforma basadas en este patrón:

Clases DeviceOrientationService que usan el destino múltiple basado en carpetas.

Para obtener más información, consulte Configuración de varios destinos.