There must be some reason... otherwise we wouldn't have withoutImplicitStartAccessing in the first place ;)
First off, as a clarification, "withoutImplicitStartAccessing" does NOT mean "don't call startAccessingSecurityScopedResource" for me. To quote the documentation:
"Bookmarks that you create without security scope automatically carry implicit ephemeral security scope."
...
"When using this option, other processes can’t call startAccessingSecurityScopedResource on the resolved URL."
Behind the scenes, what actually happens when you resolve a bookmark is:
-
You pass the bookmark data to a daemon ("ScopedBookmarkAgent").
-
The daemon validates the security scope, resolves the bookmark, then passes the resolved URL back to you.
...and "implicit ephemeral security scope"
is what then allows your app to call startAccessingSecurityScopedResource on the URL it just got. Your app then calls "startAccessingSecurityScopedResource" to take "ownership" of the resource. The open/save panel works exactly the same way, except they happen to call "startAccessingSecurityScopedResource" before returning the URL to you.
In terms of the reason it's public, they are:
-
There are specific places where the system wants to pass a URL over to an app, but be sure that the URL it gives the app WON'T also give the app access to that resource. For example, all NSWorkspace "urlForApplication(...)" methods. Most of the time, the app will already have access (because the app is in "/Applications/"), but Launch services doesn't want to have to worry/predict all of the "oddball" edge cases.
-
We want to use the same public API because having a duplicate SPI that's ALMOST the same is a pain.
-
We could keep the flag secret/private, but that opens the door to developers complaining because they passed the flag in by accident and things broke "mysteriously". If the flag is public, then there isn't any mystery.
-
It's vaguely possible SOMEONE might have the same need as the system does, so why not make it public?
FWIW, iOS UIDocumentPickerViewController provides you with a URL for startAccessingSecurityScopedResource has not been called yet. I guess this is another difference between the two platforms.
Yes.
But so should be the case on macOS, no?
It is, but that doesn't mean there's a good solution. The interaction model of iOS and macOS are basically the polar opposites of each other. On iOS, you start with "apps" and those apps then manage their own files. On macOS, you "start" with the file system and then supply files to apps. Think about the main way you open files on macOS— it isn't through the open/save panels, it's by double-clicking on the Finder or by dragging onto the app.
On macOS, the app sandbox does constrain how much of the file system an app can "see“; however, we can't really do anything about the fact that the overall filesystem is more "human readable". It's that way because that's how it has to work.
Which means I have to deleteLastPathComponent to get to the app URL... but that URL was not exactly the one user gave permission for. Maybe because of that, localizedName doesn't work?
No, this doesn't matter. The API just isn't "wired" up the way it would need to be.
But then you're asking about apps specifically, so I'm not sure if this is what you're looking for.
The issue he's looking at here is how an app communicates to the user which of the user’s files the user is interacting with. On macOS, this is handled by showing the user the path to the file, but that doesn't work on iOS because our UUID usage means the paths aren't usable.
Apple considers installed apps to be privacy-sensitive.
We do, but that doesn't mean we don't need to solve the underlying problem. For example, one solution would be to allow the app to push "back" to Files.app*, providing the same functionality as "Show in Finder". In any case, please file a bug on this and post the bug number back here.
*Strictly speaking, this is doable today, but the URL scheme is not documented, so it shouldn't be used.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware