Fun quirk of sqlite is that if you BEGIN DEFERRED and then do a read
statement and then another process concurrently does a write and then
the first process does a write statement on the same transaction, it
will immediately return SQLITE_BUSY because it's impossible to do a
write against a past version of the database. To fix this we need to use
BEGIN IMMEDIATE to take a write lock upfront on any transaction that
will need to write.
We can instead just run cleanup periodically on a codepath that is
called when the user is actively using the file provider, rather than
burning CPU time in the background when not necessary.
If you start the file provider before opening the app for the first
time, it can't open the rootfs and won't be able to display anything.
Make it return an error in this case instead of crashing.
Fixes#978
A bunch of people have tried to build the app from source and got confused when it crashed, because they customized the app group but didn't update the preprocessor macro. Now the app reads its app group off the mach-o on disk.
This also fixes AltStore, which has to change app group names too.
Fixes#650