Patterns and techniques for evaluating and improving AI agent outputs.
日本語の概要は準備中です。原文の説明を表示しています。
Optimizes MAUI for iOS/Catalyst. Native AOT pipeline, size/startup gains, library gaps, trimming.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Native AOT compilation for .NET MAUI on iOS and Mac Catalyst: compilation pipeline, publish profiles, up to 50% app size reduction and up to 50% startup improvement, library compatibility gaps, opt-out mechanisms, trimming interplay (RD.xml, source generators), and testing AOT builds on device.
Version assumptions: .NET 8.0+ baseline. Native AOT for MAUI is available on iOS and Mac Catalyst. Android uses a different compilation model (CoreCLR in .NET 11, Mono/AOT in .NET 8-10).
Cross-references: [skill:dotnet-maui-development] for MAUI patterns, [skill:dotnet-maui-testing] for testing AOT builds, [skill:dotnet-native-aot] for general AOT patterns, [skill:dotnet-aot-wasm] for WASM AOT, [skill:dotnet-ui-chooser] for framework selection.
Native AOT on iOS and Mac Catalyst compiles .NET IL directly to native machine code at publish time, eliminating the need for a JIT compiler or IL interpreter at runtime. This produces a self-contained native binary that links against platform frameworks.
.app bundle with a native executable (no IL assemblies shipped)
<!-- Enable Native AOT for iOS/Mac Catalyst -->
<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0-ios' Or
'$(TargetFramework)' == 'net8.0-maccatalyst'">
<PublishAot>true</PublishAot>
<!-- Optional: strip debug symbols for smaller binary -->
<StripSymbols>true</StripSymbols>
</PropertyGroup>
```text
```bash
# Publish with AOT for iOS
dotnet publish -f net8.0-ios -c Release -r ios-arm64
# Publish with AOT for Mac Catalyst
dotnet publish -f net8.0-maccatalyst -c Release -r maccatalyst-arm64
# Publish for iOS simulator (for AOT testing without device)
dotnet publish -f net8.0-ios -c Release -r iossimulator-arm64
```text
### Entitlements and Provisioning
AOT builds require the same entitlements and provisioning profiles as regular iOS/Catalyst builds. No additional
entitlements are needed for AOT specifically.
```xml
<!-- iOS entitlements (Entitlements.plist) -->
<!-- Standard entitlements; AOT does not require special entries -->
```xml
---
## Size Reduction
Native AOT can achieve **up to 50% app size reduction** compared to interpreter/JIT mode on iOS. The size improvement
comes from:
- **Tree shaking:** Only reachable code is included in the final binary
- **No IL shipping:** The app bundle does not include .NET IL assemblies
- **No runtime JIT:** The JIT compiler and associated metadata are not packaged
### Typical Size Comparison
| Mode | Approximate Size | Notes |
| -------------------------------- | ---------------- | ------------------------------------ |
| Interpreter (default .NET 8 iOS) | ~60-80 MB | Includes IL assemblies + interpreter |
| Native AOT | ~30-45 MB | Native binary only, no IL |
| Native AOT + StripSymbols | ~25-40 MB | Debug symbols stripped |
**Caveat:** Actual size reduction depends on app complexity, third-party library usage, and how much code is reachable
after trimming. Libraries that use heavy reflection may prevent aggressive trimming and reduce size gains.
---
## Startup Improvement
Native AOT provides **up to 50% faster cold startup** on iOS and Mac Catalyst. The startup improvement comes from:
- **No JIT warmup:** Code is already native; no compilation at app launch
- **No IL loading:** No need to load and parse .NET assemblies
- **Reduced memory pressure:** Smaller working set during startup
### Measuring Startup
```csharp
// Instrument startup timing
public partial class App : Application
{
private static readonly long StartTicks = Stopwatch.GetTimestamp();
public App()
{
InitializeComponent();
MainPage = new AppShell();
var elapsed = Stopwatch.GetElapsedTime(StartTicks);
System.Diagnostics.Debug.WriteLine(
$"App startup: {elapsed.TotalMilliseconds:F0}ms");
}
}
```text
```bash
# Use Xcode Instruments for precise startup measurement
# Time Profiler template → measure "pre-main" + "post-main" time
# Compare AOT vs non-AOT builds on the same device
```bash
---
## Library Compatibility
Many .NET libraries are not fully AOT-compatible. Common compatibility issues stem from:
- **Reflection:** Runtime type inspection, `Type.GetType()`, `Activator.CreateInstance()`
- **Dynamic code generation:** `System.Reflection.Emit`, `System.Linq.Expressions.Compile()`
- **Serialization without source generators:** JSON/XML serializers that use reflection
### Compatibility Matrix
| Library / Feature | AOT Status | Workaround |
| ----------------------------- | ---------- | ----------------------------------------------------------------------------- |
| System.Text.Json (source gen) | Compatible | Use `[JsonSerializable]` context |
| System.Text.Json (reflection) | Breaks | Switch to source generators |
| CommunityToolkit.Mvvm | Compatible | Source-gen based, AOT-safe |
| Entity Framework Core | Partial | Precompiled queries; no dynamic LINQ |
| Newtonsoft.Json | Breaks | Migrate to System.Text.Json with source gen |
| AutoMapper | Breaks | Use Mapperly (source gen) |
| MediatR | Partial | Register handlers explicitly, avoid assembly scanning |
| HttpClient | Compatible | Standard usage works |
| MAUI Essentials | Compatible | Platform APIs are AOT-safe |
| SQLite-net | Compatible | Uses P/Invoke, AOT-safe |
| Refit | Breaks | Use Refit 7+ (includes source generator; enable with `[GenerateRefitClient]`) |
| FluentValidation | Partial | Avoid runtime expression compilation |
### Detecting Incompatible Code
```xml
<!-- Enable AOT analysis warnings during development -->
<PropertyGroup>
<EnableAotAnalyzer>true</EnableAotAnalyzer>
<!-- Also enable trim analyzer (AOT requires trimming) -->
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
</PropertyGroup>
```text
AOT analysis produces warnings like `IL3050` (RequiresDynamicCode) and `IL2026` (RequiresUnreferencedCode). Address
these before publishing with AOT.
---
## Opt-Out Mechanisms
### Disabling AOT Entirely
```xml
<!-- Disable Native AOT (use interpreter/JIT mode) -->
<PropertyGroup>
<PublishAot>false</PublishAot>
</PropertyGroup>
```text
### Per-Assembly Trimming Overrides
When a specific library is not AOT-compatible, you can preserve it from trimming while still using AOT for the rest of
the app:
```xml
<!-- Preserve a specific assembly from trimming -->
<ItemGroup>
<TrimmerRootAssembly Include="IncompatibleLibrary" />
</ItemGroup>
```text
### Opt-Out of .NET 11 Defaults
.NET 11 introduces new defaults that interact with AOT:
```xml
<!-- Revert XAML source gen (use legacy XAMLC) -->
<PropertyGroup>
<MauiXamlInflator>XamlC</MauiXamlInflator>
</PropertyGroup>
<!-- Revert to Mono runtime on Android (not related to iOS AOT,
but relevant for the overall MAUI AOT story) -->
<PropertyGroup>
<UseMonoRuntime>true</UseMonoRuntime>
</PropertyGroup>
```text
---
## Trimming Interplay
Native AOT requires trimming. When `PublishAot` is true, trimming is automatically enabled. Understanding trimming
configuration is essential for a successful AOT build.
### ILLink Descriptors for Reflection Preservation
> **Note:** In Xamarin/Mono-era documentation, these were called "rd.xml" (Runtime Directives). In .NET 8+ Native AOT,
> use ILLink descriptor XML files instead.
When code uses reflection that the trimmer cannot statically analyze, use an ILLink descriptor XML file to preserve
types. You can also use `[DynamicDependency]` attributes for fine-grained preservation in code.
**ILLink descriptor XML (preferred for bulk preservation):**
```xml
<!-- ILLink.Descriptors.xml -- preserve types needed at runtime -->
<linker>
<!-- Preserve all public members of a type -->
<assembly fullname="MyApp">
<type fullname="MyApp.Models.LegacyConfig" preserve="all" />
<type fullname="MyApp.Services.PluginLoader">
<method name="LoadPlugin" />
</type>
</assembly>
<!-- Preserve all types in an external assembly -->
<assembly fullname="IncompatibleLibrary" preserve="all" />
</linker>
```text
```xml
<!-- Register the descriptor in .csproj -->
<ItemGroup>
<TrimmerRootDescriptor Include="ILLink.Descriptors.xml" />
</ItemGroup>
```csharp
**`[DynamicDependency]` attribute (preferred for targeted preservation):**
```csharp
using System.Diagnostics.CodeAnalysis;
// Preserve a specific method on a type
[DynamicDependency(nameof(LegacyConfig.Initialize), typeof(LegacyConfig))]
public void ConfigureApp() { /* ... */ }
// Preserve all public members of a type
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(LegacyConfig))]
public void LoadPlugins() { /* ... */ }
```text
### Source Generator Alternatives
When source generators aren't available, use `[DynamicDependency]` attributes (shown above) for targeted preservation
without ILLink XML files.
Prefer source generators over reflection to avoid trimming issues entirely:
| Reflection Pattern | Source Generator Alternative |
| --------------------------------- | ----------------------------------------------- |
| `JsonSerializer.Deserialize<T>()` | `[JsonSerializable]` context (System.Text.Json) |
| `Activator.CreateInstance<T>()` | Factory pattern with explicit registration |
| `Type.GetProperties()` | CommunityToolkit.Mvvm `[ObservableProperty]` |
| Assembly scanning for DI | Explicit `services.Add*()` registrations |
| AutoMapper reflection mapping | Mapperly `[Mapper]` source generator |
### Trimming Warnings
```bash
# Build with detailed trim warnings
dotnet publish -f net8.0-ios -c Release /p:PublishAot=true /p:TrimmerSingleWarn=false
# TrimmerSingleWarn=false shows per-occurrence warnings instead of
# one summary warning per assembly, making it easier to fix issues
```text
Common trim warnings:
- **IL2026:** Member with `RequiresUnreferencedCode` -- the member does something not guaranteed to work after trimming
- **IL2046:** Trim attribute mismatch between base/derived types
- **IL3050:** Member with `RequiresDynamicCode` -- the member generates code at runtime (incompatible with AOT)
---
## Testing AOT Builds
AOT builds can behave differently from Debug/JIT builds. Always test on a real device or simulator with an AOT-published
build before release.
### Common AOT-Only Failures
| Failure | Symptom | Fix |
| ------------------------------ | ------------------------------------- | ---------------------------------------------------------- |
| Missing type metadata | `MissingMetadataException` at runtime | Add type to ILLink descriptor or use `[DynamicDependency]` |
| Trimmed method | `MissingMethodException` | Add `[DynamicDependency]` or ILLink descriptor entry |
| Dynamic code gen | `PlatformNotSupportedException` | Replace with source generator alternative |
| Reflection-based serialization | Empty/null deserialized objects | Use `[JsonSerializable]` source gen |
| Assembly scanning | Missing services at runtime | Register services explicitly in DI |
### Testing Workflow
```bash
# 1. Build and publish with AOT for simulator (faster iteration)
dotnet publish -f net8.0-ios -c Release -r iossimulator-arm64
# 2. Install and test on simulator
# (Use Xcode or Visual Studio to deploy the .app to simulator)
# 3. Run smoke tests -- focus on:
# - App startup (no MissingMetadataException)
# - JSON deserialization (all properties populated)
# - Navigation (all pages render)
# - Platform services (biometric, camera, location)
# - Third-party SDK integration
# 4. Test on physical device before release
dotnet publish -f net8.0-ios -c Release -r ios-arm64
# Deploy via Xcode with provisioning profile
```text
### CI Integration
```bash
# CI pipeline: build AOT and run device tests via XHarness
dotnet publish -f net8.0-ios -c Release -r iossimulator-arm64 /p:PublishAot=true
xharness apple test \
--app bin/Release/net8.0-ios/iossimulator-arm64/publish/MyApp.app \
--target ios-simulator-64 \
--timeout 00:10:00 \
--output-directory test-results/aot
```text
For MAUI testing patterns (Appium, XHarness), see [skill:dotnet-maui-testing].
---
## Agent Gotchas
1. **Do not enable `PublishAot` without also enabling trim analyzers.** AOT requires trimming. Set
`<EnableTrimAnalyzer>true</EnableTrimAnalyzer>` and `<EnableAotAnalyzer>true</EnableAotAnalyzer>` during development
to catch issues early.
2. **Do not assume all NuGet packages are AOT-compatible.** Check for `IsAotCompatible` in the package's `.csproj` or
look for trim/AOT warnings when building. Many popular packages still use reflection internally.
3. **Do not use `Newtonsoft.Json` with AOT.** It relies entirely on reflection. Migrate to `System.Text.Json` with
`[JsonSerializable]` source gen contexts for AOT-safe serialization.
4. **Do not skip device testing for AOT builds.** Simulator testing catches most issues, but physical device behavior
can differ -- especially for startup timing, memory constraints, and platform service integration.
5. **Do not confuse MAUI iOS AOT with Android AOT.** MAUI Native AOT (`PublishAot`) targets iOS and Mac Catalyst only.
Android uses a different compilation model (Mono AOT in .NET 8-10, CoreCLR in .NET 11+). They are configured
separately.
---
## Prerequisites
- .NET 8.0+ with MAUI workload
- Xcode and iOS/Mac Catalyst SDKs (macOS only)
- Apple Developer account for physical device deployment
- Provisioning profile and signing certificate for device testing
---
## References
- [MAUI Native AOT](https://learn.microsoft.com/en-us/dotnet/maui/deployment/nativeaot)
- [Native AOT Deployment](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/)
- [Trim Self-Contained Applications](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options)
- [Prepare .NET Libraries for Trimming](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/prepare-libraries-for-trimming)
- [Trimming Descriptor Format](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options#descriptor-format)
- [.NET 11 Preview 1 Announcement](https://devblogs.microsoft.com/dotnet/dotnet-11-preview-1/)
Primary approach: Use Serena symbol operations for efficient code navigation:
serena_find_symbol instead of text searchserena_get_symbols_overview for file organizationserena_find_referencing_symbols for impact analysisserena_replace_symbol_body for clean modificationsWhen to use Serena vs traditional tools:
Example workflow:
# Instead of:
Read: src/Services/OrderService.cs
Grep: "public void ProcessOrder"
# Use:
serena_find_symbol: "OrderService/ProcessOrder"
serena_get_symbols_overview: "src/Services/OrderService.cs"
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Patterns and techniques for evaluating and improving AI agent outputs.
日本語の概要は準備中です。原文の説明を表示しています。
Comprehensive AI prompt engineering safety review and improvement prompt. Analyzes prompts for safety, bias, security vulnerabilities, and effectiveness while providing detailed improvement recommendations.
日本語の概要は準備中です。原文の説明を表示しています。
Use when user requests research requiring multiple sources, comprehensive analysis, or synthesis across topics - technical research, domain knowledge gathering, market analysis, or learning about complex subjects
日本語の概要は準備中です。原文の説明を表示しています。
AI-powered wiki generation for code repositories with commands, agents, and skills
日本語の概要は準備中です。原文の説明を表示しています。
Use when building .NET 10 or C# 14 applications; when using minimal APIs, modular monolith patterns, or feature folders; when implementing HTTP resilience, Options pattern, Channels, or validation; when seeing outdated patterns like old extension method syntax
日本語の概要は準備中です。原文の説明を表示しています。
Implements accessible .NET UI. SemanticProperties, ARIA, AutomationPeer, testing per platform.
日本語の概要は準備中です。原文の説明を表示しています。