It feels you are talking here about withoutImplicitSecurityStore creation option instead of withoutImplicitStartAccessing resolving option.
No, I'm talking about "withoutImplicitStartAccessing". We explicitly say it does not apply to security-scoped bookmarks:
"This option causes an implicit call to startAccessingSecurityScopedResource() on the returned URL when it’s ready to use the resource.
This option isn’t applicable to security-scoped bookmarks."
In my tests, withoutImplicitStartAccessing does pretty much what it says on the tin.
You're testing on iOS, not macOS. As I said earlier:
"If it's feasible, I'd recommend testing your code as a "native" macOS app (not the simulator or in compatibility mode). macOS is better at enforcing the "right" behavior, so code that works there will generally work on iOS."
I'll state that more directly— the internal implementation of iOS means that some things work that really shouldn't. The right approach here is to use macOS as the guide.
Breaking down a few specifics:
- Create a bookmark (without specifying neither withoutImplicitSecurityStore nor withSecurityScope).
This works on iOS because the system is basically ONLY creating security-scoped bookmarks. It doesn't work on macOS.
- Resolve bookmark specifying withoutImplicitStartAccessing.
- Access the URL— that would fail.
- Call startAccessingSecurityScopedResource on it - it returns true.
You can see the correct code for this here, which shows that resolving "withSecurityScope" requires you to call "startAccessing".
- If instead of 4 above you resolve the bookmark without specifying withoutImplicitStartAccessing, then
- access the URL - that would work right away.
I'd need to do a deep dive to sort out what's going on here, but I think you're basically going down the secondary code path that's used to support bookmark IPC (the same mechanism the open panel uses). Again, this ONLY works on iOS because historical details mean that "all" bookmarks end up having security scope attached. The code above fails completely on macOS.
FYI, I grabbed the "BookmarksBench.swift" file you'd attached to your bugs and on macOS it matches what I'm describing above. The one detail is that you need to quit and relaunch the app after you select a file, otherwise you end up using the access the open panel granted in the kernel.
It feels you are talking here about withoutImplicitSecurityStore creation option instead of withoutImplicitStartAccessing resolving option.
Part of what complicates this entire discussion is that the bookmark API is used to both preserve URL access and save data references. Strictly speaking, all the code above is (sort of) within the API contract. Your app never created a security-scoped bookmark, which means it got implicit access when resolve succeeded and it could disable access using withoutImplicitSecurityScope. The problem here is the words "when resolve succeeded". Strictly speaking, resolve did not need to succeed and it would NOT have succeeded on macOS.
In any case, relying on this mechanism is a mistake. The right approach here is to use exactly the same code macOS does. That means:
The pattern above is the only pattern that's specifically documented to actually "work". There are absolutely other sequences that work, but relying on those other sequences is a mistake. The exceptions are either bugs or they work because of odd edge cases/details. Either way, those other flows aren't something you can rely on.
You mean it's doable to get the app name from the Application/2A6A7975-6CE1-40F0-B7D0-18A6E64C0D89/ url via some undocumented means?
No. What I was referring to is the system providing a way that your app could open up Files.app and have it show the file you passed in. We haven't documented a URL scheme for that, but a bit of searching will show that "shareddocuments://" isn't really secret either.
Thank you for the bugs and following up on this one:
FB19996364 - "iOS and macOS: bookmarkData expected to fail but it doesn't"
You gave this example flow in your bug:
- on macOS: run the attached app in Xcode
- tap "Pick File" and select a file
- tap "Stop Access" (this is important as macOS picker just called start access on the URL).
- tap "Create bookmark" - that succeeds
- tap "Resolve bookmark" - that succeeds
- tap "Read" - that fails with NSUnderlyingError=0x6000007fa0d0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
I think this happens because you're creating a standard bookmark, not a security scoped bookmark. I'd need to dig into the code to be sure of the details, but I suspect the standard creation succeeds because the URL object itself already has the metadata bookmark creation needs, so the system never checks against the sandbox. However, security scoped creation fails at #3.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware