Skip to content

Commit f0fab0b

Browse files
adrianhallCopilot
andauthored
(#135) Document the Native AOT requirements (#185)
* (#135) Document the Native AOT requirements * Update docs/content/in-depth/client/maui-aot-support.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 88ac053 commit f0fab0b

File tree

37 files changed

+1137
-618
lines changed

37 files changed

+1137
-618
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
+++
2+
title = "Native AOT Support for MAUI"
3+
weight = 30
4+
+++
5+
6+
When using [Native AOT with .NET MAUI](https://learn.microsoft.com/dotnet/maui/deployment/nativeaot), several requirements will need to be met to ensure the application works in release mode, explicitly on iOS and Mac Catalyst.
7+
8+
1. [Implement compiled models for Entity Framework Core](https://learn.microsoft.com/ef/core/performance/advanced-performance-topics?tabs=with-di%2Cexpression-api-with-constant#compiled-models).
9+
2. [Implement source generation in System.Text.Json](https://learn.microsoft.com/dotnet/standard/serialization/system-text-json/source-generation).
10+
3. [Enable the Interpreter for iOS and Mac Catalyst](https://learn.microsoft.com/dotnet/maui/macios/interpreter?view=net-maui-8.0#enable-the-interpreter).
11+
12+
The following are basic instructions on how to fulfill these requirements. However, you should consult the official documentation (linked above) for each requirement.
13+
14+
> [!NOTE]
15+
> Thanks to [Richard Perry](https://github.com/richard-einfinity) for providing the detailed instructions for enabling Native AOT support.
16+
17+
## Compiled models
18+
19+
To enable compiled models in your MAUI project:
20+
21+
1. Move your `DbContext` and models to a separate library that targets `net8.0`.
22+
2. Create a dummy project with a project reference to the library. This will act as a startup project for the EF Core Tools we will run later. This can be as simple as a console application.
23+
3. Implement an `IDesignTimeDbContextFactory` for your context. This can be placed in your dummy project. For example:
24+
25+
```csharp
26+
internal class MyContextFactory : IDesignTimeDbContextFactory<MyContext>
27+
{
28+
public MyContext CreateDbContext(string[] args)
29+
{
30+
var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
31+
optionsBuilder.UseSqlite("Data Source=:memory:");
32+
return new MyContext(optionsBuilder.Options, new HttpClientOptions());
33+
}
34+
}
35+
```
36+
37+
4. Ensure you have the [EF Core Tools](https://learn.microsoft.com/ef/core/cli/dotnet) installed.
38+
5. Run the following command (appropriately adjusted for your situation):
39+
40+
```powershell
41+
Optimize-DbContext \
42+
-OutputDir Models \
43+
-Context MyContext \
44+
-StartupProject MyDummyProject \
45+
-Project MyLibraryProject \
46+
-Namespace MyLibraryProject.Models
47+
```
48+
49+
Type this command on a single line. This should generate the compiled models in the specified output directory. We will be interested in the class named `MyContextModel` later.
50+
51+
6. In your `MauiProgram.cs` file, add the following statement as the first statement in the `CreateMauiApp()` method:
52+
53+
```csharp
54+
AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue31751", true);
55+
```
56+
57+
This addresses a deadlock issue in the compiled model initialization.
58+
59+
7. In your `DbContext` configuration, use the following statement:
60+
61+
```csharp
62+
options.UseModel(MyContextModel.Instance);
63+
```
64+
65+
Your `DbContext` initialization should look something like this:
66+
67+
```csharp
68+
mauiAppBuilder.Services.AddDbContext<MyContext>((sp, options) =>
69+
{
70+
options.UseSqlite(sp.GetRequiredService<SqliteConnection>());
71+
options.UseModel(MyContextModel.Instance);
72+
});
73+
```
74+
75+
## Source generation for System.Text.Json
76+
77+
Create a new partial class that inherits from `JsonSerializerContext`. It should look like this:
78+
79+
```csharp
80+
[JsonSerializable(typeof(Page<TodoItem>))]
81+
[JsonSerializable(typeof(Page<Category>))]
82+
[JsonSourceGenerationOptions(
83+
PropertyNameCaseInsensitive = true,
84+
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
85+
DictionaryKeyPolicy = JsonKnownNamingPolicy.CamelCase,
86+
UseStringEnumConverter = true,
87+
WriteIndented = false,
88+
GenerationMode = JsonSourceGenerationMode.Metadata,
89+
AllowTrailingCommas = true,
90+
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
91+
Converters = [
92+
typeof(JsonStringEnumConverter),
93+
typeof(DateTimeConverter),
94+
typeof(DateTimeOffsetConverter),
95+
typeof(TimeOnlyConverter),
96+
typeof(SpatialGeoJsonConverter)
97+
]
98+
)]
99+
public partial class MySerializerContext : JsonSerializerContext
100+
{
101+
}
102+
```
103+
104+
Add a `JsonSerializable` attribute for each entity that is stored in your `DbContext` similar to the ones in the example above. Finally, install the modified `JsonSerializerContext` in the `MauiProgram.cs` as the second statment in the `CreateMauiApp` function:
105+
106+
```csharp
107+
DatasyncSerializer.JsonSerializerOptions.TypeInfoResolver = MySerializerContext.Default;
108+
```
109+
110+
## Enable the Interpreter
111+
112+
Add the following property to the iOS release configuration in your MAUI app project file:
113+
114+
```xml
115+
<MtouchInterpreter>all</MtouchInterpreter>
116+
```
117+
118+
The property group should look something like the following:
119+
120+
```xml
121+
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net8.0-ios|AnyCPU'">
122+
<OptimizePNGs>true</OptimizePNGs>
123+
<MtouchInterpreter>all</MtouchInterpreter>
124+
</PropertyGroup>
125+
```
126+
127+
## Having problems
128+
129+
Unfortunately, the development team does not have much experience with releasing iOS applications, so is of limited help. While you can [add a discussion](https://github.com/CommunityToolkit/Datasync/discussions), you will probably get more assistance in the [MAUI](https://github.com/dotnet/maui) and [Entity Framework Core](https://github.com/dotnet/efcore) projects.
130+

docs/public/404.html

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head><script src="/Datasync/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=Datasync/livereload" data-no-instant defer></script>
44
<meta charset="utf-8">
55
<meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0, minimum-scale=1.0">
6-
<meta name="generator" content="Hugo 0.139.0">
6+
<meta name="generator" content="Hugo 0.140.2">
77
<meta name="generator" content="Relearn 6.2.0+tip">
88
<meta name="description" content="">
99
<meta name="author" content="">
@@ -20,17 +20,17 @@
2020
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
2121
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
2222
<link rel="manifest" href="/favicon/site.webmanifest">
23-
<link href="/Datasync/css/fontawesome-all.min.css?1734123542" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/Datasync/css/fontawesome-all.min.css?1734123542" rel="stylesheet"></noscript>
24-
<link href="/Datasync/css/nucleus.css?1734123542" rel="stylesheet">
25-
<link href="/Datasync/css/auto-complete.css?1734123542" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/Datasync/css/auto-complete.css?1734123542" rel="stylesheet"></noscript>
26-
<link href="/Datasync/css/perfect-scrollbar.min.css?1734123542" rel="stylesheet">
27-
<link href="/Datasync/css/fonts.css?1734123542" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/Datasync/css/fonts.css?1734123542" rel="stylesheet"></noscript>
28-
<link href="/Datasync/css/theme.css?1734123542" rel="stylesheet">
29-
<link href="/Datasync/css/theme-auto.css?1734123542" rel="stylesheet" id="R-variant-style">
30-
<link href="/Datasync/css/chroma-auto.css?1734123542" rel="stylesheet" id="R-variant-chroma-style">
31-
<link href="/Datasync/css/variant.css?1734123542" rel="stylesheet">
32-
<link href="/Datasync/css/print.css?1734123542" rel="stylesheet" media="print">
33-
<script src="/Datasync/js/variant.js?1734123542"></script>
23+
<link href="/Datasync/css/fontawesome-all.min.css?1736358756" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/Datasync/css/fontawesome-all.min.css?1736358756" rel="stylesheet"></noscript>
24+
<link href="/Datasync/css/nucleus.css?1736358756" rel="stylesheet">
25+
<link href="/Datasync/css/auto-complete.css?1736358756" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/Datasync/css/auto-complete.css?1736358756" rel="stylesheet"></noscript>
26+
<link href="/Datasync/css/perfect-scrollbar.min.css?1736358756" rel="stylesheet">
27+
<link href="/Datasync/css/fonts.css?1736358756" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/Datasync/css/fonts.css?1736358756" rel="stylesheet"></noscript>
28+
<link href="/Datasync/css/theme.css?1736358756" rel="stylesheet">
29+
<link href="/Datasync/css/theme-auto.css?1736358756" rel="stylesheet" id="R-variant-style">
30+
<link href="/Datasync/css/chroma-auto.css?1736358756" rel="stylesheet" id="R-variant-chroma-style">
31+
<link href="/Datasync/css/variant.css?1736358756" rel="stylesheet">
32+
<link href="/Datasync/css/print.css?1736358756" rel="stylesheet" media="print">
33+
<script src="/Datasync/js/variant.js?1736358756"></script>
3434
<script>
3535
window.relearn = window.relearn || {};
3636
window.relearn.relBasePath='.';

docs/public/categories/index.html

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head><script src="/Datasync/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=Datasync/livereload" data-no-instant defer></script>
44
<meta charset="utf-8">
55
<meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0, minimum-scale=1.0">
6-
<meta name="generator" content="Hugo 0.139.0">
6+
<meta name="generator" content="Hugo 0.140.2">
77
<meta name="generator" content="Relearn 6.2.0+tip">
88
<meta name="description" content="">
99
<meta name="author" content="">
@@ -20,17 +20,17 @@
2020
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
2121
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
2222
<link rel="manifest" href="/favicon/site.webmanifest">
23-
<link href="/Datasync/css/fontawesome-all.min.css?1734123542" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/Datasync/css/fontawesome-all.min.css?1734123542" rel="stylesheet"></noscript>
24-
<link href="/Datasync/css/nucleus.css?1734123542" rel="stylesheet">
25-
<link href="/Datasync/css/auto-complete.css?1734123542" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/Datasync/css/auto-complete.css?1734123542" rel="stylesheet"></noscript>
26-
<link href="/Datasync/css/perfect-scrollbar.min.css?1734123542" rel="stylesheet">
27-
<link href="/Datasync/css/fonts.css?1734123542" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/Datasync/css/fonts.css?1734123542" rel="stylesheet"></noscript>
28-
<link href="/Datasync/css/theme.css?1734123542" rel="stylesheet">
29-
<link href="/Datasync/css/theme-auto.css?1734123542" rel="stylesheet" id="R-variant-style">
30-
<link href="/Datasync/css/chroma-auto.css?1734123542" rel="stylesheet" id="R-variant-chroma-style">
31-
<link href="/Datasync/css/variant.css?1734123542" rel="stylesheet">
32-
<link href="/Datasync/css/print.css?1734123542" rel="stylesheet" media="print">
33-
<script src="/Datasync/js/variant.js?1734123542"></script>
23+
<link href="/Datasync/css/fontawesome-all.min.css?1736358756" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/Datasync/css/fontawesome-all.min.css?1736358756" rel="stylesheet"></noscript>
24+
<link href="/Datasync/css/nucleus.css?1736358756" rel="stylesheet">
25+
<link href="/Datasync/css/auto-complete.css?1736358756" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/Datasync/css/auto-complete.css?1736358756" rel="stylesheet"></noscript>
26+
<link href="/Datasync/css/perfect-scrollbar.min.css?1736358756" rel="stylesheet">
27+
<link href="/Datasync/css/fonts.css?1736358756" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/Datasync/css/fonts.css?1736358756" rel="stylesheet"></noscript>
28+
<link href="/Datasync/css/theme.css?1736358756" rel="stylesheet">
29+
<link href="/Datasync/css/theme-auto.css?1736358756" rel="stylesheet" id="R-variant-style">
30+
<link href="/Datasync/css/chroma-auto.css?1736358756" rel="stylesheet" id="R-variant-chroma-style">
31+
<link href="/Datasync/css/variant.css?1736358756" rel="stylesheet">
32+
<link href="/Datasync/css/print.css?1736358756" rel="stylesheet" media="print">
33+
<script src="/Datasync/js/variant.js?1736358756"></script>
3434
<script>
3535
window.relearn = window.relearn || {};
3636
window.relearn.relBasePath='..';
@@ -163,12 +163,12 @@ <h1 id="categories">Categories</h1>
163163
<script>
164164
var contentLangs=['en'];
165165
</script>
166-
<script src="/Datasync/js/auto-complete.js?1734123542" defer></script>
167-
<script src="/Datasync/js/lunr/lunr.min.js?1734123542" defer></script>
168-
<script src="/Datasync/js/lunr/lunr.stemmer.support.min.js?1734123542" defer></script>
169-
<script src="/Datasync/js/lunr/lunr.multi.min.js?1734123542" defer></script>
170-
<script src="/Datasync/js/lunr/lunr.en.min.js?1734123542" defer></script>
171-
<script src="/Datasync/js/search.js?1734123542" defer></script>
166+
<script src="/Datasync/js/auto-complete.js?1736358756" defer></script>
167+
<script src="/Datasync/js/lunr/lunr.min.js?1736358756" defer></script>
168+
<script src="/Datasync/js/lunr/lunr.stemmer.support.min.js?1736358756" defer></script>
169+
<script src="/Datasync/js/lunr/lunr.multi.min.js?1736358756" defer></script>
170+
<script src="/Datasync/js/lunr/lunr.en.min.js?1736358756" defer></script>
171+
<script src="/Datasync/js/search.js?1736358756" defer></script>
172172
</div>
173173
<div id="R-homelinks" class="default-animation homelinks">
174174
<ul>
@@ -200,7 +200,8 @@ <h1 id="categories">Categories</h1>
200200
<li data-nav-id="/Datasync/in-depth/server/databases/sqlite/index.html" class=""><a class="padding" href="/Datasync/in-depth/server/databases/sqlite/index.html">Sqlite</a></li></ul></li></ul></li>
201201
<li data-nav-id="/Datasync/in-depth/client/index.html" class="alwaysopen"><a class="padding" href="/Datasync/in-depth/client/index.html">Client application</a><ul id="R-subsections-60c8d76d913730d5c907aa0f8134456a" class="morespace collapsible-menu">
202202
<li data-nav-id="/Datasync/in-depth/client/online-operations/index.html" class=""><a class="padding" href="/Datasync/in-depth/client/online-operations/index.html">Online operations</a></li>
203-
<li data-nav-id="/Datasync/in-depth/client/auth/index.html" class=""><a class="padding" href="/Datasync/in-depth/client/auth/index.html">Authentication</a></li></ul></li></ul></li>
203+
<li data-nav-id="/Datasync/in-depth/client/auth/index.html" class=""><a class="padding" href="/Datasync/in-depth/client/auth/index.html">Authentication</a></li>
204+
<li data-nav-id="/Datasync/in-depth/client/maui-aot-support/index.html" class=""><a class="padding" href="/Datasync/in-depth/client/maui-aot-support/index.html">Native AOT Support for MAUI</a></li></ul></li></ul></li>
204205
</ul>
205206
</div>
206207
<div class="padding footermargin footerLangSwitch footerVariantSwitch footerVisitedLinks footerFooter showFooter"></div>
@@ -253,8 +254,8 @@ <h1 id="categories">Categories</h1>
253254
</div>
254255
</div>
255256
</aside>
256-
<script src="/Datasync/js/clipboard.min.js?1734123542" defer></script>
257-
<script src="/Datasync/js/perfect-scrollbar.min.js?1734123542" defer></script>
258-
<script src="/Datasync/js/theme.js?1734123542" defer></script>
257+
<script src="/Datasync/js/clipboard.min.js?1736358756" defer></script>
258+
<script src="/Datasync/js/perfect-scrollbar.min.js?1736358756" defer></script>
259+
<script src="/Datasync/js/theme.js?1736358756" defer></script>
259260
</body>
260261
</html>

docs/public/css/chroma-auto.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
@import "chroma-relearn-light.css?1734123542" screen and (prefers-color-scheme: light);
2-
@import "chroma-relearn-dark.css?1734123542" screen and (prefers-color-scheme: dark);
1+
@import "chroma-relearn-light.css?1736358756" screen and (prefers-color-scheme: light);
2+
@import "chroma-relearn-dark.css?1736358756" screen and (prefers-color-scheme: dark);

docs/public/css/format-print.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
@import "theme-relearn-light.css?1734123542";
2-
@import "chroma-relearn-light.css?1734123542";
1+
@import "theme-relearn-light.css?1736358756";
2+
@import "chroma-relearn-light.css?1736358756";
33

44
#R-sidebar {
55
display: none;

docs/public/css/print.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
@import "format-print.css?1734123542";
1+
@import "format-print.css?1736358756";

docs/public/css/swagger.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* Styles to make Swagger-UI fit into our theme */
22

3-
@import "fonts.css?1734123542";
4-
@import "variables.css?1734123542";
3+
@import "fonts.css?1736358756";
4+
@import "variables.css?1736358756";
55

66
body{
77
line-height: 1.574;

docs/public/css/theme-auto.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
@import "theme-relearn-light.css?1734123542" screen and (prefers-color-scheme: light);
2-
@import "theme-relearn-dark.css?1734123542" screen and (prefers-color-scheme: dark);
1+
@import "theme-relearn-light.css?1736358756" screen and (prefers-color-scheme: light);
2+
@import "theme-relearn-dark.css?1736358756" screen and (prefers-color-scheme: dark);

docs/public/css/variant.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@import "variables.css?1734123542";
1+
@import "variables.css?1736358756";
22

33
html {
44
color-scheme: only var(--INTERNAL-BROWSER-theme);

0 commit comments

Comments
 (0)