javascriptiospromisemobile-safarifile-system-access-api

File System Access API on Safari iOS - createSyncAccessHandle() UnknownError: 'invalid platform file handle'


I'm currently refactoring an app to use the OPFS to save images on an iPad for a use-case where a user needs to take pictures in a location that doesn't have wi-fi but storing all of the images in RAM will cause the iPad to crash.

I've managed to create a working OPFS Worker that works on my local Windows machine on Chrome and Firefox, but I can't get it working on the test iPad. [EDIT] What it does is sends the base64 text to the worker and saves it as a text file, that I can retrieve later.

The iPad I'm using to test is iOS version 16.3.1.

The iPad I'm trying to develop for is iOS version 15.7.3.

As far as I can tell, Safari iOS has had OPFS compatibility since 15.2.

I was able to narrow down the problem to one specific error (via Web Inspector):

Unhandled Promise Rejection: UnknownError: invalid platform file handle

It references back to the following code (within a Web Worker):

    const root = await navigator.storage.getDirectory();
    const saveHandle = await root.getFileHandle(input.fileName, { create: true });
    const access = await saveHandle.createSyncAccessHandle(); //<-- ERROR

input.fileName is usually something like S0I0.txt, based off a labeling system I have for organizing the images.

It doesn't seem to matter if the file is being created by getFileHandle() or not.

I haven't been able to extract anything else from the Error object.

I also have been unable to find any reference to this specific error anywhere. It's not on the list of Exceptions on the web docs. In fact, the only reference to the exact phrase I've found is on an old ticket from 2013.

As far as I can tell, the 2 preceding statements work correctly and generate the right objects, being FileSystemDirectoryHandle and FileSystemFileHandle, respectively.

[UPDATE]:

I did some more digging and found some references to reserved filenames (like con on Windows) so I tried some tests using different filenames (like test1.txt) and I also tried removing the { create: true } clause with no success.

I'm starting to feel like this is a compatibility issue, but that doesn't sound right seeing as multiple sources say that Safari iOS 15.2 and later can support OPFS, but not the rest of the File System Access API. Am I unwittingly using an incompatible part of the FSA API?


Solution

  • This was an issue on WebKit's side that was reported in https://bugs.webkit.org/show_bug.cgi?id=251460, which is marked as fixed. It might be that your devices don't have a Safari version that includes this fix, since Safari releases are bound to the operating system. If your app is publicly accessibly, I'm happy to test on one of my devices, which all are on whatever the latest beta version may be.