Platform‑Specific Development in .NET MAUI
While .NET MAUI provides a single codebase for iOS, Android, macOS, and Windows, certain scenarios require native APIs that are not abstracted by MAUI. This tutorial shows how to call platform‑specific functionality safely and effectively.
Why Platform‑Specific Code?
- Access to hardware‑specific features (e.g., biometric authentication)
- Utilizing latest OS capabilities before they are added to MAUI
- Performance optimisations that rely on native SDKs
Approaches
1️⃣ Partial Classes & Conditional Compilation
// MyService.cs
public partial class MyService
{
public partial void PlatformInit();
}
// MyService.android.cs
#if ANDROID
using Android.Widget;
public partial class MyService
{
public partial void PlatformInit()
{
// Android specific initialization
Toast.MakeText(Android.App.Application.Context, "Android init", ToastLength.Short).Show();
}
}
#endif
2️⃣ Dependency Service (Legacy)
// IDeviceInfo.cs
public interface IDeviceInfo
{
string GetModel();
}
// DeviceInfo.iOS.cs
using Foundation;
[assembly: Dependency(typeof(DeviceInfo_iOS))]
public class DeviceInfo_iOS : IDeviceInfo
{
public string GetModel() => UIDevice.CurrentDevice.Model;
}
// Usage
var model = DependencyService.Get<IDeviceInfo>().GetModel();
3️⃣ Microsoft.Maui.Devices
(Modern)
using Microsoft.Maui.Devices;
string model = DeviceInfo.Current.Model;
Platform‑Specific UI
You can tailor UI components per platform using OnPlatform
or Handlers
.
Using OnPlatform
in XAML
<Label Text="Welcome!">
<Label.FontSize>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="iOS" Value="24"/>
<On Platform="Android" Value="22"/>
<On Platform="WinUI" Value="20"/>
</OnPlatform>
</Label.FontSize>
</Label>
Custom Handler Example (C#)
#if ANDROID
using Microsoft.Maui.Handlers;
using Android.Views;
public class MyButtonHandler : ButtonHandler
{
protected override Android.Views.Button CreatePlatformView()
{
var btn = base.CreatePlatformView();
btn.SetAllCaps(true); // Android‑specific property
return btn;
}
}
#endif
Best Practices
- Wrap platform code in services or partial classes – keep core logic platform‑agnostic.
- Guard calls with
#if
directives orDeviceInfo.Current.Platform
checks. - Prefer
Microsoft.Maui.Essentials
(nowMicrosoft.Maui.Devices
) where available. - Write unit tests for the shared code; mock platform services if needed.