iosswiftios-sharesheetfiles-app

How to read file shared from iOS Files app


I have an app that allows me to export (and import) its contents. While working to replace the deprecated 'unarchiveTopLevelObjectWithData' unarchiveTopLevelObjectWithData (still ongoing) I ran into some issues testing. My test was that I had previously exported to the Files app and from there using the share sheet I sent it to my app. This was not working. In the past I had imported files from an app like WhatsApp and that worked fine.

After some troubleshooting I discovered that for some reason when sharing from the Files app (and not just iCloud Drive) I get a different URL for the file than I get from other apps. If my file in the Files app is in iCloud Drive I get the following path:

/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs

When I move the file to the 'On My iPhone' location and share from there I get:

/private/var/mobile/Containers/Shared/AppGroup/***/File Provider Storage/Files

What my app is built to work with is that when a non-Files app shares a file it's put in an 'Inbox' subfolder of the Documents folder. So what my app currently does is check in that location. Now I've modified the app to take the URL from the 'application:openURL:options:' method. But when I use that URL to check the existence of the file using 'FileManager.default.fileExists' it can't find it.

What do I need to do to allow my app to access the urls produced by the Files app?


Solution

  • I found this article that got me a working solution. What is required is that you need to treat the URL as a 'SecurityScopedResource' and you have to start and stop accessing it. Modified code snippet from the above article:

    guard url.startAccessingSecurityScopedResource() else {
       throw ImportError.accessDenied // Or return
    }
    do { 
       //Process your URL as usual
       url.stopAccessingSecurityScopedResource() 
    }
    

    By using this opening files from the Files app will work and by extension AirDropping files will work as well. One thing to note, sharing a file in this way did remove the file from the Files app. This is what I want, but seems like something to be aware of if you don't want that to happen.