Context
I'm using the NSFileCoordinator
& NSFilePresenter
in a sandboxed application to access SQLite database files and their secondary files (e.g. WAL or journal files) as per https://developer.apple.com/documentation/foundation/nsfilepresenter/1415415-primarypresenteditemurl
E.g. something similar to this:
var presenters: [NSFilePresenter] = ["wal", "journal", "shm"].map { ext in
let presenter = SQLiteTempFilePresenter(databaseId: databaseContext.id, sqliteMainFile: url, newExt: ext)
// addFilePresenter needs to be balanced with a `removeFilePresenter`. See SQLiteTempFilePresenter#deinit
NSFileCoordinator.addFilePresenter(presenter)
return presenter
}
That way there will be a NSFilePresenter
for each possible secondary SQLite file (e.g. with the main file being foo/bar/database.sqlite
there will be presenter for each of the secondary files foo/bar/database.sqlite-shm
and foo/bar/database.sqlite-wal
)
Using NSFilePresenter
to work with SQLite files within the Sandbox environment works as expected.
Desired change
I'd like to expand the usage of NSFileCoordinator
to react to changes to the SQLite files that happen outside of the application.
To achieve that I added an additional NSFilePresenter
for the main file (e.g. foo/bar/database.sqlite
) that has a func presentedItemDidChange()
method. That method does get called when I change the corresponding SQLite file (e.g. by using the sqlite3
command line tool).
So far so good. But in WAL mode (https://www.sqlite.org/wal.html), changes to the SQLite file don't immediately change the file itself but get written to the write-ahead-log first (e.g. foo/bar/database.sqlite-wal
in this example). Only when the outside connection is closed, will the changes be committed to the main SQLite file itself. At which point the NSFilePresenter#presentedItemDidChange()
method will be called. So I also like to be notified when the secondary files change.
Adding a presentedItemDidChange()
callback method to the SQLiteTempFilePresenter
instances for the secondary files does not seem to work, the method never gets called even though the corresponding secondary files change.
Questions
-
If I add another instance of the
NSFilePresenter
for each of the secondary files, the callbackpresentedItemDidChange()
gets called for the secondary files as well. Having two different instance of theNSFilePresenter
for a single URL (one for sandboxing purposes, the other for being notified of file changes) seems a bit fishy though. Is that the intended (or at least an acceptable) way of usingNSFilePresenter
? -
The documentation for NSFilePresenter states that "If another process uses a file coordinator for the same file or directory, your presenter objects are similarly notified whenever the other process makes its changes." I do get notified though when using the
sqlite3
command line tool which does not use aNSFileCoordinator
. Is there any documentation that explains that behaviour? I mean it's great that it seems to work but I'd like to understand why.