maui-accessibility
Guide for making .NET MAUI apps accessible — screen reader support via SemanticProperties, heading levels, AutomationProperties…
.NET MAUI runtime permissions guidance — checking and requesting permissions, PermissionStatus handling, custom permissions via BasePlatformPermission, platform-specific manifest/plist declarations, and DI-friendly service patterns. USE FOR: "request permission", "check
$ npx -y skills add davidortinau/maui-skills --skill maui-permissions --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/maui-permissionsContext preview
The summary Claude sees to decide when to auto-load this skill.
.NET MAUI runtime permissions guidance — checking and requesting permissions, PermissionStatus handling, custom permissions via BasePlatformPermission, platform-specific manifest/plist declarations, and DI-friendly service patterns. USE FOR: "request permission", "check
name: maui-permissions description: > .NET MAUI runtime permissions guidance — checking and requesting permissions, PermissionStatus handling, custom permissions via BasePlatformPermission, platform-specific manifest/plist declarations, and DI-friendly service patterns. USE FOR: "request permission", "check permission", "PermissionStatus", "runtime permission", "BasePlatformPermission", "custom permission", "Android manifest permission", "Info.plist permission", "permission denied handling". DO NOT USE FOR: geolocation-specific permissions (use maui-geolocation), camera/photo permissions (use maui-media-picker), or notification permissions (use maui-local-notifications).
// ❌ Shows prompt even if already granted
var status = await Permissions.RequestAsync<Permissions.Camera>();
// ✅ Check first — avoids unnecessary prompts
var status = await Permissions.CheckStatusAsync<Permissions.Camera>();
if (status != PermissionStatus.Granted)
status = await Permissions.RequestAsync<Permissions.Camera>();Permission APIs are async and require a UI context. Constructors can't await.
// ❌ Blocks the UI thread or throws
public MyViewModel()
{
var status = Permissions.RequestAsync<Permissions.Camera>().Result;
}
// ✅ Use OnAppearing, a command, or async initialization
protected override async void OnAppearing()
{
await CheckAndRequestPermissionAsync<Permissions.Camera>();
}// ❌ Only checks for Granted — misses edge cases
if (status == PermissionStatus.Granted) { /* proceed */ }
// ✅ Handle all relevant statuses
switch (status)
{
case PermissionStatus.Granted: /* proceed */ break;
case PermissionStatus.Limited: /* iOS partial access */ break;
case PermissionStatus.Denied:
case PermissionStatus.Restricted:
await ShowSettingsPromptAsync(); break;
}iOS shows the system permission dialog **only once per permission, ever**. After denial, `RequestAsync` returns `Denied` immediately without showing UI. You must guide the user to **Settings → App → Permission**.
`ShouldShowRationale` returns `true` only **after** a prior denial (but not after "Don't ask again"). Use it to show explanatory UI before re-requesting:
if (Permissions.ShouldShowRationale<Permissions.Camera>())
{
await Shell.Current.DisplayAlert("Permission needed",
"Camera access is required to scan barcodes.", "OK");
}
status = await Permissions.RequestAsync<Permissions.Camera>();On Android 13+, `StorageRead` and `StorageWrite` always return `Granted` (scoped storage makes them meaningless). Use granular media permissions instead:
// ❌ Always returns Granted on API 33+ — gives false confidence await Permissions.RequestAsync<Permissions.StorageRead>(); // ✅ Use the specific media permission await Permissions.RequestAsync<Permissions.Photos>(); // photo access await Permissions.RequestAsync<Permissions.Media>(); // audio/video
Windows doesn't have runtime permission dialogs for most features. Declare capabilities in `Package.appxmanifest` instead.
The recommended pattern handles iOS one-shot and Android rationale:
public async Task<PermissionStatus> CheckAndRequestPermissionAsync<T>()
where T : Permissions.BasePermission, new()
{
var status = await Permissions.CheckStatusAsync<T>();
if (status == PermissionStatus.Granted)
return status;
if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.iOS)
return status; // iOS won't show dialog again
if (Permissions.ShouldShowRationale<T>())
{
await Shell.Current.DisplayAlert("Permission needed",
"This feature requires the requested permission.", "OK");
}
return await Permissions.RequestAsync<T>();
}A collection of 41 skills for .NET MAUI development, UI/UX design reasoning, and Xamarin migration, designed for use with GitHub Copilot CLI and Claude Code.
Guide for making .NET MAUI apps accessible — screen reader support via SemanticProperties, heading levels, AutomationProperties…
.NET MAUI view animations, custom animations, easing functions, rotation, scale, translation, and fade effects. USE FOR: "animate…
.NET MAUI app icon configuration, splash screen setup, SVG to PNG conversion at build time, composed/adaptive icons, and…
.NET MAUI app lifecycle guidance covering the four app states (not running, running, deactivated, stopped), cross-platform Window…
Guide for .NET MAUI apps consuming .NET Aspire-hosted backend services. Covers AppHost configuration, service discovery for…
Add authentication to .NET MAUI apps. Covers WebAuthenticator for generic OAuth 2.0 / social login, and MSAL.NET for Microsoft…