SQLite in MAUI App not working on iOS
See original GitHub issueDescription
I firstly use SQLite-net-plc package to connect my MAUI app to SQLite database. Everything works OK on Android phone, but I got error on iOS. I got error which is mentioned and still not resolved here: https://github.com/dotnet/maui/issues/3211
Then I want to make this works by official Microsoft package EFCore SQLite: Microsoft.EntityFrameworkCore.Sqlite Everything works OK again only on Android and not on iOS. What’s wrong? I think this is critical issue, because feature to connect to database is necessary on MAUI platform. I started with this official Xamarin EFCore tutorial (https://docs.microsoft.com/en-us/ef/core/get-started/xamarin) and rewrite it to my view how this could work in MAUI.
Steps to Reproduce
- Create new .NET MAUI App or .NET MAUI Blazor App
- Create Model named Blog.cs:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
- Create DBContext class named BloggingContext:
public class BloggingContext : DbContext
{
public BloggingContext(DbContextOptions<BloggingContext> options) : base(options)
{
try
{
SQLitePCL.Batteries_V2.Init();
this.Database.EnsureCreated();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
public DbSet<Blog> Blogs { get; set; }
}
- Inside MauiProgram class you have to register DBContext: a) Example for .NET MAUI Blazor App:
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.RegisterBlazorMauiWebView()
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
string dbPath = Path.Combine(FileSystem.AppDataDirectory, "blogs.db3");
builder.Services.AddDbContext<BloggingContext>(options => options.UseSqlite($"Filename={dbPath}"));
builder.Services.AddBlazorWebView();
builder.Services.AddSingleton<WeatherForecastService>();
return builder.Build();
}
b) Example for .NET MAUI App:
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
builder.Services.AddSingleton<MainPage>();
string dbPath = Path.Combine(FileSystem.AppDataDirectory, "blogs.db3");
builder.Services.AddDbContext<BloggingContext>(options => options.UseSqlite($"Filename={dbPath}"));
return builder.Build();
}
- You have to work with something in your database: a) Example for .NET MAUI Blazor App - add this lines into index.razor:
@code {
protected override async Task OnInitializedAsync()
{
try
{
Blog blog = new Blog()
{
BlogId = 1,
Url = "http://www.google.si"
};
await dbContext.AddAsync(blog);
await dbContext.SaveChangesAsync();
var stZapisovVBazi = dbContext.Blogs.Count();
Debug.WriteLine(stZapisovVBazi);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
b) Example for .NET MAUI App - add this lines into MainPage.xaml.cs file:
public MainPage(BloggingContext dbContext)
{
InitializeComponent();
try
{
Blog blog = new Blog()
{
BlogId = 1,
Url = "http://www.google.si"
};
dbContext.Add(blog);
dbContext.SaveChanges();
var stZapisovVBazi = dbContext.Blogs.Count();
Debug.WriteLine(stZapisovVBazi);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
You have to take mainPage instance with DI in App class:
public App(MainPage mainPage)
{
InitializeComponent();
MainPage = mainPage;
}
- Run app on Android Emulator. Everything works OK.
- Run app on iPhone 12 iOS 15.2 remote iOS simulator (via connected Mac). App crashes at line:
SQLitePCL.Batteries_V2.Init();
Version with bug
Preview 12 (current)
Last version that worked well
Unknown/Other
Affected platforms
iOS
Affected platform versions
iPhone 12 iOS 15.2, Xcode 13.2.1, VS 17.1.0 Preview 5.0 on Windows 10 (connected to remote Mac)
Did you find any workaround?
No response
Relevant log output
System.TypeInitializationException: The type initializer for 'Microsoft.Data.Sqlite.SqliteConnection' threw an exception.
---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.DllNotFoundException: e_sqlite3
at SQLitePCL.SQLite3Provider_e_sqlite3.SQLitePCL.ISQLite3Provider.sqlite3_libversion_number()
at SQLitePCL.raw.SetProvider(ISQLite3Provider imp)
at SQLitePCL.Batteries_V2.Init()
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
--- End of inner exception stack trace ---
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Microsoft.Data.Sqlite.Utilities.BundleInitializer.Initialize()
at Microsoft.Data.Sqlite.SqliteConnection..cctor()
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal.SqliteRelationalConnection.CreateDbConnection()
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.get_DbConnection()
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.BeginTransaction(IsolationLevel isolationLevel)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.BeginTransaction()
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList`1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(StateManager stateManager, Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<>c.<SaveChanges>b__104_0(DbContext _, ValueTuple`2 t)
at Microsoft.EntityFrameworkCore.Storage.NonRetryingExecutionStrategy.Execute[ValueTuple`2,Int32](ValueTuple`2 state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
Issue Analytics
- State:
- Created 2 years ago
- Comments:13 (7 by maintainers)
Thanks Take care
Just FYI:
I’ve been investigating this problem at:
ericsink/SQLitePCL.raw#468
and @RaspeR87 has posted a repro there,
and I thought perhaps the following might be of interest here:
Building inside VS 17.1 (preview 5) produces different build output than building from the command line. From a nuget package, a different assembly is copied into the build output directory.
More details are present in the comments on that issue, and there might be good reasons for this behavior, but it certainly seems kinda wrong to see these two build operations doing different things.