Hmmm. Let me check this tonight, I'll get back with my findings.
An addendum: I just noticed that if a user manually sets a label from the Finder, this label:
So it almost seems like if you set the labels in code, you can read them and remove them. If you set them manually in the Finder, they are inaccessible to Read/SetLabels methods.
... I couldn't help but check immediately :-) There is a legacy finder info attribute that stores single labels (and other info). Meaning that sometimes, the label info can be stored there instead of the new com.apple.metadata:_kMDItemUserTags attribute.
To remove all labels with a simpler command:
xattr -d com.apple.metadata:_kMDItemUserTags /path/to/file
This will leave the last single label if stored in com.apple.FinderInfo. To remove it:
xattr -d com.apple.FinderInfo /path/to/file
BUT com.apple.FinderInfo also stores other info. Although it's legacy info from the Classic environment, you should check if there's anything useful for you. One example is the 4 character file type code. Here's a link to a page that documents this attribute
From my (non scientific) experiments, it seems that setting the first label from the Finder will set it using com.apple.FinderInfo IF this attribute is present. After removing it, if you set it again in the Finder, it's then correctly stored in the new attribute.
I haven't poked around to decode the com.apple.FinderInfo attribute to extract the label set there, but it should be feasible.
thanks Bruno, this makes sense and explains the odd behavior. Just for the record, creating a manual label from the Finder will resist clearance by xattr -d com.apple.metadata:_kMDItemUserTags. You must also execute xattr -d com.apple.FinderInfo in addition. This is on a freshly created file from TextEdit so no chance of some old legacy attributes hanging around. Odd that Apple would store labels under different com.apple.XXX files.
Yeah, my tests are similar with new files created on Mojave. Sorry if I misled you in thinking that old files were the culprit. It seems that sometimes the Finder still creates the old attribute, so probably some legacy code buried in MacOS :-) I would guess that the first label uses the old attribute, and that any additional label get set with the new one.
Glad it works for you. I'm going to make a more elegant class to read set and clear the labels. I can send it to you if you're interested.
Thanks Bruno, I'd appreciate looking at your class. One other point I just noticed during testing: seems that xattr is a python script and unfortunately, compared to FinderLabelMBS, it is extremely slow, at least on a large folder tree (3000 files: 15 min and still running :-( ) on a remote server. So there is no easy way to efficiently manage ALL labels it seems. Just an FYI if your application also includes complex hierarchies.
My guess is that the slow process comes from instantiating a shell with every call. Try to make a call with a wildcard to process a batch of files. I did a quick test locally directly in terminal and processing 539 files with xattr -d com.apple.metadata:_kMDItemUserTags took 148ms and xattr -d com.apple.FinderInfo took 151ms. I know a file server adds quite a bit of lag but maybe you'll want to see if a wildcard helps. Try it directly in the terminal, transpose in a shell in Xojo after.
If I extract a list of items in a folder and set each one at a time using FinderLabelMBS it's faster than xattr with the -r flag, BUT FinderLabelMBS only seems to manipulate the classic labels, not the com.apple.metadata:_kMDItemUserTags, so it's not that useful because you end up with dual labels, a mix of new and old, and it becomes a mess. I wish we could just pass an array of numbers (= color indexes) to a function that would stamp none, one or several color labels to a folderItem, and quickly, taking care of new and old sets at once.
I have searched a bit but the only other way I found (at a high level anyways) is using Applescript. I doubt it'll be faster, but it may be worth a try.
At this point, you may want to contact Christian about this. He may be willing to update its classes to support both old and new attributes.
As for me, I'll work on a clean class during the Christmas Holiday (for fun). If it can be useful, even if it's slow, I'll happily pass it along. It can work as you described, but it'll still be slow on a remote volume.
@Bruno F As for me, I'll work on a clean class during the Christmas Holiday (for fun). If it can be useful, even if it's slow, I'll happily pass it along. It can work as you described, but it'll still be slow on a remote volume.
I would also be interested in seeing your class. I only need read ability, but I can see how we ability would be useful too.