FileProviderUI prepare method receives internal fileprovider ID list instead of actual itemIdentifier

In the context of a FPUIActionExtensionViewController module the prepare method is defined like this:

override func prepare(forAction actionIdentifier: String,
                      itemIdentifiers: [NSFileProviderItemIdentifier]) {

So you would expect the itemIdentifiers list to be the item identifier but instead it is a list of the internal fileprovider IDs like: __fp/fs/docID(6595461)

So this is a bit problematic because the only way to recover the ID is by using getUserVisibleURL to get the path which is not great.

Is there a better way ?

Am I missing something ?

Thanks,

Answered by DTS Engineer in 855384022

So you would expect the itemIdentifiers list to be the item identifier, but instead it is a list of the internal file provider IDs like: __fp/fs/docID(6595461)

I'm a bit confused by the distinction you're making here. What I'd expect it to return is the identifier the file provider uses to track files...

So this is a bit problematic because the only way to recover the ID is by using getUserVisibleURL to get the path, which is not great.

...which is the same identifier you map to a URL using "getUserVisibleURL".

Am I missing something ?

The key thing to understand here is that the File Provider system prefers to use item identifiers (instead of paths) because it needs to be able to differentiate between "the file object" (meaning, the logical data construct you're actually managing) and "the file path" (meaning, the location at which an object might happen to be located). That distinction is critical to how file systems actually work but isn't necessarily obvious to developers who are used to thinking of the file system purely in terms of paths.

In this particular case, it allows the system to tell you what objects you should be manipulating without worrying that other changes that are happening in parallel will change the meaning of the action the user actually requested.

Is there a better way ?

Better how? The immediate question I have here is "what are you actually trying to do"? In most cases, I'd expect your infrastructure to already be operating in terms of file provider IDs, so you wouldn't necessarily need to map them to a URL at all.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

So you would expect the itemIdentifiers list to be the item identifier, but instead it is a list of the internal file provider IDs like: __fp/fs/docID(6595461)

I'm a bit confused by the distinction you're making here. What I'd expect it to return is the identifier the file provider uses to track files...

So this is a bit problematic because the only way to recover the ID is by using getUserVisibleURL to get the path, which is not great.

...which is the same identifier you map to a URL using "getUserVisibleURL".

Am I missing something ?

The key thing to understand here is that the File Provider system prefers to use item identifiers (instead of paths) because it needs to be able to differentiate between "the file object" (meaning, the logical data construct you're actually managing) and "the file path" (meaning, the location at which an object might happen to be located). That distinction is critical to how file systems actually work but isn't necessarily obvious to developers who are used to thinking of the file system purely in terms of paths.

In this particular case, it allows the system to tell you what objects you should be manipulating without worrying that other changes that are happening in parallel will change the meaning of the action the user actually requested.

Is there a better way ?

Better how? The immediate question I have here is "what are you actually trying to do"? In most cases, I'd expect your infrastructure to already be operating in terms of file provider IDs, so you wouldn't necessarily need to map them to a URL at all.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thanks for your answer.

The distinction I am making is between the arbitrary itemIdentifier field that I am managing in my workingSet and the internal fileprovider item id that starts with __fp/fs/fileID...

I have no way to link the internal fileprovider ID to my own workingSet ID so my only workaround right now is to use the path which is not good.

What I find pretty strange is that the NSFileProviderCustomAction performAction call in the main fileprovider extension receives the right itemIdentifier while the prepare call in the FPUI module receives __fp/fs/fileID... IDs which are useless.

And yes you are correct that this is indeed the ID I am using with the getUserVisibleURL to get the path but evidently it seems that it might be able to work with both kinds of IDs.

What I find pretty strange is that the NSFileProviderCustomAction performAction call in the main fileprovider extension receives the right itemIdentifier while the prepare call in the FPUI module receives __fp/fs/fileID... IDs which are useless.

So, I spent some more time looking into this and the difference is basically caused by the context they're called in. The "__fp/fs" ID your UI extension receives is the "broader" format that the broader system uses to track file provider items, and it's what's passed into your UI extension because it's the only ID the Finder has access to.

Conversely, the reason you get a different identifier here:

What I find pretty strange is that the NSFileProviderCustomAction performAction call in the main fileprovider extension receives the right itemIdentifier while the prepare call in the FPUI module receives __fp/fs/fileID... IDs which are useless.

...is (basically) that the "conversion" into your workingSet ID happened earlier when the action was originally transferred into your file provider extension.

And yes, you are correct that this is indeed the ID I am using with the getUserVisibleURL to get the path but evidently it seems that it might be able to work with both kinds of IDs.

Yes. There are actually different code (one is SPI) paths involved with the different ID types, but getUserVisibleURL handles both.

And, yes, you're right that isn't the most elegant architecture.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

FileProviderUI prepare method receives internal fileprovider ID list instead of actual itemIdentifier
 
 
Q