In reply to a comment from Marian Rainer-Harbach, I wanted to suggest an answer that I’m not 100% firm about, but does reflect my greater familiarity with iPadOS gained over the last eight months. I believe the answer to my question is a firm “no”: iOS and iPadOS apps (including the Files app) cannot create files on an external share except in very circumscribed cases.¹
The issue here is with app sandboxing:
Generally, apps are restricted to accessing files inside their own sandbox, meaning the files and directories they were installed with. Aside from temporary cache files, this is the only way apps can address files simply by name.
This is something I’ve learned from using apps like the Blink ssh/mosh shell, Pythonista, iVim, Termius, and other apps that can provide Unix shell-like access or other ways of specifying files by pathname. I’ve supplemented this learning-by-experience a bit with some research in the Apple Developer docs, but I don’t claim expertise here as an app developer.²
So: iPadOS apps can access files contained in their sandbox directory, like
/private/var/mobile/Containers/Data/Application/$appID, or its subdirectories, by name (in read-write mode if they so choose), but outside that directory (in superfolders or siblings), they only have by-name access to securely-shared componentized resources (nearly always only in read-only mode), and they generally have no visibility at all into other apps’ sandboxes.
Yet iPadOS apps can, obviously, access files elsewhere in at least two circumstances:
- An iCloud Documents directory created for the app; and
- Files shared with the app via a Share sheet.
The iCloud directory is created by the app developer’s using CloudKit, and has a specific naming convention: in the Blink shell, for instance, the files I can find in the Files app under iCloud Drive → Blink are available in the Blink shell under the symbolic link
If I read that symlink, I can find:
blink> ls -l iCloud lrwxr-xr-x 1 mobile mobile 91 Mar 17 14:53 iCloud -> /private/var/mobile/Library/Mobile Documents /iCloud~com~carloscabanero~blinkshell/Documents
Thus, apps using CloudKit can “break out of their sandbox”, but only to the extent of reaching what amounts to a second iCloud sandbox, limited to only their own iCloud Documents data.
This is why, since the introduction of iPadOS (iOS > v13) and the Files app, some iPad apps sport a file-opening screen that looks very like the Files app; via the
UIDocumentBrowserViewController interface, they give the user the ability to use a Finder-like interface for managing an app’s files.
However, as similar as they look (so similar, in, fact, that you could be forgiven for thinking it was simply Files being used as a helper app), there’s a key difference between this
UIDocumentBrowserViewController interface and the Files app: when you tap iCloud Drive in the Files app, you find a directory listing all the various CloudKit-compatible apps you have installed, each as subdirectories you can navigate to. But when you tap iCloud Drive in an app using the
UIDocumentBrowserViewController interface, you’re immediately taken to the iCloud Documents subdirectory for that app; you can’t “escape” and look at other apps’ iCloud documents.
Share sheets are the other way apps can potentially get access to files outside their sandbox. However, this is user-initiated (via a Share operation), and the file-like object the app receives is not accessible simply by pathname. You won’t find an app that includes a “Recents” list with files shared via Share sheet, because once an app has lost reference to a file object given it by handoff from the Share sheet, it no longer has a way to access it again (unlike files in its own sandbox, which it can access at any time by name).
Usually, that means the app being Shared to has no ability to create a file—that would be mucking with another app’s sandbox by name and isn’t allowed.
(There’s an exception for “bundles”—objects in macOS/iOS/iPadOS like apps that appear to be files, but are actually directories—on macOS you can right-click on an app in the Finder and choose to “Open bundle” to see this. When bundles are shared with appropriate permissions, the shared-to app may be able to create files inside the bundle.)³
While not fully answering all my questions, I think this background at least explains the issue: except for Shared bundles, apps simply can’t create files anywhere except inside their own sandbox. While the Files app—as a system utility—has greater access than other iPadOS/iOS apps to browse the file tree (including mounts of network drives), it still doesn’t have the right to create files outside its own sandbox by name, which is what would be required to allow the functionality I was asking about.
While app sandboxing exists in macOS—for all apps installed from the Store, and many other apps too, as Apple has pushed developers to implement app sandboxing in their macOS apps—it’s an ever-present security measure in iOS and iPadOS that, unlike on macOS, can’t be ignored by ordinary developers, not even with the coöperation of users (assuming they haven’t jailbroken their devices).
The Finder is a macOS app that isn’t subject to sandboxing rules. iPadOS’s Files app looks like Finder, so at its first introduction it was perhaps reasonable for users to expect it to work like Finder, too. But as an iOS/iPadOS app, even though it does have special access, Files still has to play by (most of) the rules—meaning no file creation in random places in the filesystem hierarchy.
¹ This discussion doesn’t really pertain to Secure Enclave storage, which has its own, entirely separate, set of requirements. But it should probably be obvious that the concepts of “Secure Enclave storage” and “network storage” can’t overlap!
² This is why I am posting this answer to my own question, but I’m not accepting it unless and until it gets a number of upvotes to suggest it is, in fact, the right answer—perhaps commenters will have corrections or suggestions.
³ There’s also an exception when an app shares a subdirectory of its own with another app; in the Blink shell, for instance, you can use the command
open to give, say, an editor access to text files inside a Blink documents subdirectory. But even in this case, this just allows the other app to open and export to files in the foreign directory; it doesn’t get full read-write access.