# Maui Speech To Text

> >

- **Type:** Skill
- **Install:** `agentstack add skill-davidortinau-maui-skills-maui-speech-to-text`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [davidortinau](https://agentstack.voostack.com/s/davidortinau)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [davidortinau](https://github.com/davidortinau)
- **Source:** https://github.com/davidortinau/maui-skills/tree/main/plugins/maui-skills/skills/maui-speech-to-text

## Install

```sh
agentstack add skill-davidortinau-maui-skills-maui-speech-to-text
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Speech-to-Text — Gotchas & Best Practices

For full service implementation, types, and UI integration patterns, see `references/speech-to-text-api.md`.

## Critical: Permission Handling

Always request permissions **before** starting speech recognition. Both microphone and speech permissions are required.

```csharp
// ❌ Starting recognition without checking permissions
var result = await _speechService.StartListeningAsync();

// ✅ Always check permissions first
if (!await _speechService.RequestPermissionsAsync())
    return; // Gracefully handle denial
var result = await _speechService.StartListeningAsync(cancellationToken);
```

### ⚠️ iOS Requires Both Permission Descriptions

Missing either `NSSpeechRecognitionUsageDescription` or `NSMicrophoneUsageDescription` in Info.plist will cause a **runtime crash** — not a graceful failure.

### ⚠️ Android: Permission Re-prompt

On Android, if the user denies the `RECORD_AUDIO` permission twice, the OS stops showing the prompt. You must guide users to Settings manually.

## Common Mistakes

### ❌ No Timeout — Indefinite Listening

Always set a timeout to prevent indefinite listening sessions that drain battery:

```csharp
// ❌ No timeout — listens forever if no speech detected
await _speechToText.StartListenAsync(options, CancellationToken.None);

// ✅ Use a combined timeout + user cancellation token
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(60));
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(
    userCancellationToken, timeoutCts.Token);
await _speechToText.StartListenAsync(options, combinedCts.Token);
```

### ❌ Not Unsubscribing Event Handlers

Leaking event subscriptions causes duplicate processing and memory leaks:

```csharp
// ❌ Subscribe without unsubscribe
_speechToText.RecognitionResultUpdated += OnRecognitionResultUpdated;

// ✅ Always unsubscribe in finally block
try
{
    _speechToText.RecognitionResultUpdated += OnRecognitionResultUpdated;
    // ... listen ...
}
finally
{
    _speechToText.RecognitionResultUpdated -= OnRecognitionResultUpdated;
}
```

### ❌ Not Disposing CancellationTokenSource

```csharp
// ❌ Leaked CTS
_currentCts = new CancellationTokenSource();

// ✅ Dispose in finally
try { /* ... */ }
finally
{
    _currentCts?.Dispose();
    _currentCts = null;
}
```

## Platform Pitfalls

| Platform | Pitfall |
|----------|---------|
| iOS | Missing either plist key → **runtime crash** |
| Android | User denies permission twice → OS stops prompting; must redirect to Settings |
| All | No timeout → battery drain from indefinite listening |
| All | Calling `StartListeningAsync` while already listening → returns error, not exception |

## Architecture Tips

1. **Wrap `ISpeechToText` in a service** — Don't use `SpeechToText.Default` directly in ViewModels. Wrap in `ISpeechRecognitionService` for testability and state management.

2. **Use partial results for UX** — Subscribe to `PartialResultReceived` for live transcription feedback. Users expect to see words appear as they speak.

3. **Continuous listening = loop with delay** — Loop `StartListeningAsync` with small delays (`Task.Delay(100)`) for conversation mode.

4. **Guard against double-start** — Check state before starting:
   ```csharp
   if (State == SpeechRecognitionState.Listening)
       return new SpeechRecognitionResultDto { Success = false, ErrorMessage = "Already listening" };
   ```

5. **Natural language output** — CommunityToolkit.Maui returns normalized, punctuated text — not raw phonemes. No post-processing needed for basic use cases.

6. **UI-agnostic service** — The `ISpeechRecognitionService` pattern works identically with XAML/MVVM, C# Markup, and MauiReactor. See `references/speech-to-text-api.md` for all three patterns.

## Checklist

- [ ] `CommunityToolkit.Maui` NuGet installed (look up current version)
- [ ] `UseMauiCommunityToolkit()` called in `MauiProgram.cs`
- [ ] `ISpeechToText` registered as singleton via DI
- [ ] iOS: Both `NSSpeechRecognitionUsageDescription` and `NSMicrophoneUsageDescription` in Info.plist
- [ ] Android: `RECORD_AUDIO` permission in AndroidManifest.xml
- [ ] Permissions checked before every `StartListeningAsync` call
- [ ] Timeout configured (recommend 60 seconds max)
- [ ] Event handlers unsubscribed in `finally` blocks
- [ ] `CancellationTokenSource` disposed after use

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [davidortinau](https://github.com/davidortinau)
- **Source:** [davidortinau/maui-skills](https://github.com/davidortinau/maui-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-davidortinau-maui-skills-maui-speech-to-text
- Seller: https://agentstack.voostack.com/s/davidortinau
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
