Accessing Platform-Specific APIs
One of the powerful features of .NET MAUI is its ability to abstract platform-specific APIs while still allowing direct access when necessary. This enables you to leverage unique features of each operating system (Windows, macOS, Android, iOS) within your cross-platform application.
Why Access Platform APIs?
- Utilize platform-unique features not yet covered by .NET MAUI abstractions.
- Integrate with existing native SDKs.
- Optimize performance for specific platform functionalities.
Using the INativeInfoProvider
Interface
.NET MAUI provides the Microsoft.Maui.Essentials.Implementations.NativeInfoProvider
class which implements the INativeInfoProvider
interface. This interface allows you to get information about the underlying native platform.
Example: Getting the Operating System Version
Here's how you can retrieve the operating system version for the current platform:
using Microsoft.Maui.Essentials.Implementations;
// ...
public void DisplayOSVersion()
{
var nativeInfo = new NativeInfoProvider();
string osVersion = nativeInfo.OperatingSystemVersion;
System.Diagnostics.Debug.WriteLine($"Current OS Version: {osVersion}");
// You could display this in a UI element, e.g., a Label
// MyLabel.Text = $"Current OS Version: {osVersion}";
}
Platform-Specific Projects
For more direct access, you can utilize the platform-specific projects within your .NET MAUI solution. Each project (e.g., `Platforms/Windows`, `Platforms/Android`, `Platforms/iOS`, `Platforms/MacCatalyst`) contains native code that you can call.
Using Conditional Compilation
You can use preprocessor directives to write code that is compiled only for specific platforms.
#if ANDROID
// Code specific to Android
var androidContext = Android.App.Application.Context;
// ... use Android APIs
#elif IOS
// Code specific to iOS
var uiWindow = UIKit.UIApplication.SharedApplication.KeyWindow;
// ... use iOS APIs
#elif WINDOWS
// Code specific to Windows
var window = Microsoft.UI.Xaml.Window.Current;
// ... use Windows APIs
#endif
Sharing Code with Platform Abstractions
The recommended approach for most scenarios is to create abstractions in your .NET MAUI project and then implement those abstractions in each platform-specific project. This keeps your core logic clean and reusable.
1. Define an Interface in your .NET MAUI Project
// In your .NET MAUI project (e.g., Services/IDeviceInfoService.cs)
namespace MyMauiApp.Services
{
public interface IDeviceInfoService
{
string GetDeviceModel();
string GetOperatingSystem();
}
}
2. Implement the Interface in Platform Projects
// In Platforms/Android/DeviceInfoService.cs
using MyMauiApp.Services;
using Android.OS; // Namespace for Android APIs
namespace MyMauiApp.Android
{
public class DeviceInfoService : IDeviceInfoService
{
public string GetDeviceModel()
{
return Build.Model;
}
public string GetOperatingSystem()
{
return $"Android {Build.VERSION.Release}";
}
}
}
// In Platforms/iOS/DeviceInfoService.cs
using MyMauiApp.Services;
using UIKit; // Namespace for iOS APIs
namespace MyMauiApp.iOS
{
public class DeviceInfoService : IDeviceInfoService
{
public string GetDeviceModel()
{
return UIDevice.CurrentDevice.Model;
}
public string GetOperatingSystem()
{
return $"iOS {UIDevice.CurrentDevice.SystemVersion}";
}
}
}
// Repeat for Windows and MacCatalyst
3. Register and Use the Service
Register your platform-specific implementations in your service collection, typically in the MauiProgram.cs
file.
// In MauiProgram.cs
using MyMauiApp.Services;
#if ANDROID
using MyMauiApp.Android;
#elif IOS
using MyMauiApp.iOS;
#elif WINDOWS
using MyMauiApp.Windows; // Assuming a Windows implementation
#endif
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp()
.ConfigureServices(); // Your custom configuration method
return builder.Build();
}
private static void ConfigureServices(this MauiAppBuilder builder)
{
builder.Services.AddSingleton<IDeviceInfoService, DeviceInfoService>(); // This will pick the correct implementation based on platform
}
}
Then, inject and use the service in your ViewModels or Pages:
public partial class MyViewModel : ObservableObject
{
private readonly IDeviceInfoService _deviceInfoService;
[ObservableProperty]
string deviceInfo;
public MyViewModel(IDeviceInfoService deviceInfoService)
{
_deviceInfoService = deviceInfoService;
deviceInfo = $"{_deviceInfoService.GetDeviceModel()} ({_deviceInfoService.GetOperatingSystem()})";
}
}
Note: When using dependency injection, the correct platform-specific implementation of your interface will be automatically resolved at runtime.
Tip: For common device information, consider using the built-in Microsoft.Maui.Essentials.DeviceInfo
class which provides a unified API for many platform-specific details.
Important: Always consider if a platform-specific API is truly necessary. .NET MAUI aims to provide a rich set of cross-platform APIs to minimize the need for direct platform access, leading to more maintainable and portable code.
By understanding these approaches, you can effectively harness the power of native platform capabilities within your .NET MAUI applications.