I should have said "resolve", not just "create". The use case here is a helper tool/process that's given a URL "target" (for example, through XPC) but something like (like your main app), so the user never actually selects files "for" it.
In my current app, it turned out that I don't need bookmarks. But I have apps in development that will need bookmarks for both files and directories.
I've seen some recent threads here involving bookmarks. I can't find the exact one, but I remember one in particular that discussed some complicated interactions between processes and bookmarks. In following these threads, bookmarks seem less and less straightforward.
the issue here is purely a bug.
The word "bug" is a bit of a value judgement. I think it might be better to refer to bugs as simply "behaviour". Apple might be able to differentiate between expected and unexpected behaviour. But for 3rd party developers, it's all just behaviour. The only thing that's important is that said behaviour is documented.
Stepping back for a moment, what's your larger goal here? If you're specifically interacting with volumes then the other, often better, option is to move down a level in the system and use DiskArb, which ends up bypassing most of these issues.
Currently, it's just a login item that checks volume free space. I had planned on using security-scoped bookmarks just because it seemed to be the standard way to persist URLs in a sandboxed app.
I am using Disk Arbitration, as well as IOKit, but that's for collecting additional information about the location referred to by the URL, as a URL for an external volume is not reliable. That being said, I do need to use a URL as a starting point to see if it's the correct volume.
bookmarking "/" isn't something you'd normally do anyway.
I realize that now. But the issue here is that if I allow the end user to select a URL, which in the Mac App Store, I must do, then I need to handle the location selected, by any means necessary.
"/System/Volumes/Data” -> How did you get this?
Primarily this is for FSEvents. It's not related to the login item, any security-scoped bookmarks, or any persistence issues. I was poking around to learn more about this unexpected behaviour and this seems related.
Basically, the open panel shouldn't be giving you any object you can't bookmark.
Again, "shouldn't" is a value judgement. It's my job to write code that works properly with observed behaviour, expected or otherwise. Judgements are out of scope.
Note that if you're getting file references from other sources (like navigating the hierarchy yourself), there are lots of objects that can't be bookmarked, but many of those are also in the category of "don't treat this like a file at all" (for example, the contents of /dev/).
Exactly! Thankfully, I can't even navigate to /dev in an open panel. But what about other locations? Originally, this would have been a bigger problem. I've avoided that by restricting the user selection to whole volumes. I would prefer not to do this, but "/" is likely to be a popular choice, so I have to support it. If I allow arbitrary paths, then I have to handle both the unbookmarkable / and bookmarks. I might still do that, just not tonight.
I would assume that you won't be able to restore access to a resource unless you have a security-scoped bookmark.
Yes. That was my assumption too, leading to the catch-22.
I think paths and bookmarks should be treated as fundamentally different concepts, not as replacements for each other. A path is a static reference to a precise location in the file system tree, while a bookmark is a persistent reference to an object on a particular file system.
Which is why I'd prefer to use bookmarks.
For example, a volume name collision can change the target of a path but has no effect on a bookmark.
That was one of the reasons I wanted to use bookmarks in the first place. However, I don't think that guarantee is actually documented, so I had always intended to use data from Disk Arbitration and IOKit to double-check.
But I think we're going in circles at this point. I wanted to get some clarification and I did. It's a bug new behaviour, which is likely to change in the future. But it's August 29, so macOS 26 is likely to ship with this new behaviour, so I'll need to handle it permanently, and any likely new behaviours. The internals, and public API, is far more complex than I had assumed. But I've learned some strategies to minimize the impact on my code.