This guide covers platform-specific configuration, requirements, and considerations for using Akavache across different target platforms.
Note: MAUI targets in this repository are documented for .NET 9 only. For older TFMs, please use a previous release/tag or consult historical docs. See MAUI .NET 9 Support Documentation for official guidance.
net9.0-android- Android applicationsnet9.0-ios- iOS applicationsnet9.0-maccatalyst- Mac Catalyst applicationsnet9.0-windows- Windows applications (WinUI)
// In MauiProgram.cs
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder.UseMauiApp<App>();
// Initialize Akavache early in the MAUI startup process
AppBuilder.CreateSplatBuilder()
.WithAkavacheCacheDatabase<SystemJsonSerializer>(cacheBuilder =>
cacheBuilder.WithApplicationName("MyMauiApp")
.WithSqliteProvider() // REQUIRED: Explicit provider
.WithForcedDateTimeKind(DateTimeKind.Utc)
.WithSqliteDefaults());
return builder.Build();
}
}<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<MauiVersion>9.0.0</MauiVersion>
<!-- Other MAUI configuration -->
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.0" />
<PackageReference Include="Akavache.Sqlite3" Version="11.1.*" />
<PackageReference Include="Akavache.SystemTextJson" Version="11.1.*" />
</ItemGroup>
</Project>- Initialize early in
MauiProgram.csbefore any UI components are created - Use UTC DateTimeKind to avoid timezone issues across platforms
- Consider platform differences in file system access and caching policies
- Test thoroughly on all target platforms as behavior can vary
// In App.xaml.cs
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
ConfigureAkavache();
base.OnStartup(e);
}
protected override void OnExit(ExitEventArgs e)
{
// Important: Shutdown Akavache properly to ensure data integrity
CacheDatabase.Shutdown().Wait();
base.OnExit(e);
}
private static void ConfigureAkavache()
{
AppBuilder.CreateSplatBuilder()
.WithAkavacheCacheDatabase<SystemJsonSerializer>(builder =>
builder.WithApplicationName("MyWpfApp")
.WithSqliteProvider() // REQUIRED: Explicit provider
.WithForcedDateTimeKind(DateTimeKind.Utc)
.WithSqliteDefaults());
}
}- Proper shutdown is crucial to prevent data corruption
- Thread safety - Akavache is thread-safe but consider UI thread marshaling
- File system permissions - Ensure app has write access to cache directories
- Application lifecycle - Handle suspension and resumption correctly
// In AppDelegate.cs or SceneDelegate.cs
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
AppBuilder.CreateSplatBuilder()
.WithAkavacheCacheDatabase<SystemJsonSerializer>(builder =>
builder.WithApplicationName("MyiOSApp")
.WithSqliteProvider() // REQUIRED: Explicit provider
.WithSqliteDefaults());
return base.FinishedLaunching(application, launchOptions);
}- Cache location:
Library/Caches/(not backed up by iTunes/iCloud) - Backup considerations: UserAccount cache may be backed up to iCloud
- Storage limitations: iOS may delete cache data when storage is low
// Secure cache automatically integrates with iOS Keychain
await CacheDatabase.Secure.InsertObject("sensitive_data", secretData);// In AppDelegate.cs
public override void DidEnterBackground(UIApplication application)
{
// Flush any pending writes before backgrounding
CacheDatabase.Flush().Wait();
}- Use InMemory cache sparingly - iOS has aggressive memory management
- Monitor memory warnings and clear unnecessary cached data
- Consider cache size limits based on device capabilities
// In MainActivity.cs or Application class
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
AppBuilder.CreateSplatBuilder()
.WithAkavacheCacheDatabase<SystemJsonSerializer>(builder =>
builder.WithApplicationName("MyAndroidApp")
.WithSqliteProvider() // REQUIRED: Explicit provider
.WithSqliteDefaults());
}- Cache location:
{ApplicationData}/cache/(internal storage) - External storage: Requires additional permissions for external cache
- Backup policies: Respect Android's auto-backup configuration
// In MainActivity.cs
protected override void OnPause()
{
// Ensure data is persisted before app is paused
CacheDatabase.Flush().Wait();
base.OnPause();
}<!-- In proguard-rules.pro or rules.txt -->
-keep class Akavache.** { *; }
-keep class YourApp.Models.** { *; }
-dontwarn Akavache.**- Be aware of doze mode and background execution limits
- Consider using foreground services for critical cache operations
- Handle process termination gracefully
// In App.xaml.cs
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
AppBuilder.CreateSplatBuilder()
.WithAkavacheCacheDatabase<SystemJsonSerializer>(builder =>
builder.WithApplicationName("MyUwpApp")
.WithSqliteProvider() // REQUIRED: Explicit provider
.WithSqliteDefaults());
// Rest of initialization...
}- Important: Mark your application as
x86,x64, orARM, notAny CPU - SQLite native libraries require specific architecture targeting
// In App.xaml.cs
private async void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
try
{
await CacheDatabase.Flush();
}
finally
{
deferral.Complete();
}
}<Package>
<!-- Ensure appropriate capabilities are declared -->
<Capabilities>
<Capability Name="internetClient" />
<!-- Add others as needed -->
</Capabilities>
</Package>// Always use UTC for cached DateTime values to avoid timezone issues
AppBuilder.CreateSplatBuilder()
.WithAkavacheCacheDatabase<SystemJsonSerializer>(builder =>
builder.WithApplicationName("MyApp")
.WithSqliteProvider()
.WithForcedDateTimeKind(DateTimeKind.Utc) // Ensures consistency
.WithSqliteDefaults());// Let Akavache handle platform-specific paths
// Don't hardcode file paths - use the defaults or platform-appropriate methods// Use consistent serialization across platforms
// System.Text.Json is recommended for new projects
// Newtonsoft.Json for maximum compatibility| Platform | SQLite Performance | File I/O | Memory Constraints | Network |
|---|---|---|---|---|
| iOS | Good | Restricted | High | Good |
| Android | Good | Restricted | Medium | Good |
| Windows | Excellent | Flexible | Low | Excellent |
| macOS | Excellent | Flexible | Low | Excellent |
| UWP | Good | Sandboxed | Medium | Good |
<!-- For image caching on iOS/macOS -->
<PackageReference Include="Akavache.Drawing" Version="11.1.*" /><!-- For encrypted storage on Android -->
<PackageReference Include="Akavache.EncryptedSqlite3" Version="11.1.*" /><!-- For Windows-specific drawing features -->
<PackageReference Include="Akavache.Drawing" Version="11.1.*" />[TestFixture]
public class PlatformSpecificTests
{
[Test]
[Platform(Include = "iOS")]
public async Task iOS_Specific_Behavior_Test()
{
// iOS-specific test logic
}
[Test]
[Platform(Include = "Android")]
public async Task Android_Specific_Behavior_Test()
{
// Android-specific test logic
}
}[TestFixture]
public class CrossPlatformTests
{
[Test]
public async Task Data_Should_Be_Consistent_Across_Platforms()
{
// Test that data stored on one platform can be read on another
var testData = new TestModel { Id = 1, Name = "Test" };
await CacheDatabase.UserAccount.InsertObject("test", testData);
var retrieved = await CacheDatabase.UserAccount.GetObject<TestModel>("test");
Assert.AreEqual(testData.Name, retrieved.Name);
}
}- "SQLite library not found" - Ensure proper architecture targeting
- "Keychain access denied" - Check app entitlements and permissions
- "Cache data missing after app update" - Check backup/restore settings
- "Database is locked" - Ensure proper app lifecycle handling
- "Permission denied" - Verify cache directory permissions
- "ProGuard stripped types" - Add proper keep rules
- "Architecture mismatch" - Set specific platform target (x86/x64/ARM)
- "Access denied to cache directory" - Check Windows permissions
- "App suspension data loss" - Implement proper suspension handling
public class PlatformCacheDebugger
{
public static void LogPlatformInfo()
{
Console.WriteLine($"Platform: {Environment.OSVersion}");
Console.WriteLine($"Cache directory: {CacheDatabase.GetCacheDirectory()}");
Console.WriteLine($"Available disk space: {GetAvailableDiskSpace()}");
}
}- Initialize early in the application lifecycle
- Handle suspension/termination properly on mobile platforms
- Use UTC DateTimeKind for cross-platform consistency
- Test on all target platforms - behavior can vary significantly
- Respect platform conventions for file storage and security
- Monitor platform-specific constraints like memory and storage limits
- Handle platform-specific exceptions gracefully
- Use appropriate cache types based on platform characteristics
Akavache V11.1 supports .NET Framework 4.6.2 and .NET Framework 4.7.2.
// In Application_Start or Main method
public void ConfigureAkavache()
{
AppBuilder.CreateSplatBuilder()
.WithAkavacheCacheDatabase<SystemJsonSerializer>(builder =>
builder.WithApplicationName("MyNetFrameworkApp")
.WithSqliteProvider() // REQUIRED: Explicit provider
.WithSqliteDefaults());
}- Package Installation: System.Text.Json is available via NuGet package for .NET Framework 4.6.2+
- Performance: Full performance benefits available on .NET Framework
- Compatibility: All serialization features work identically to .NET Core/.NET 5+
<!-- Required packages for .NET Framework -->
<PackageReference Include="Akavache.Sqlite3" Version="11.1.*" />
<PackageReference Include="Akavache.SystemTextJson" Version="11.1.*" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />// Ensure proper async context in .NET Framework applications
public async Task CacheOperation()
{
// Use ConfigureAwait(false) to avoid deadlocks
var data = await CacheDatabase.UserAccount
.GetObject<MyData>("key")
.ConfigureAwait(false);
}- Proper shutdown: Call
CacheDatabase.Shutdown()during application exit - App.config considerations: No special configuration required
- File permissions: Ensure appropriate file system permissions for cache directories