Is it possible to get labels of files?

Can Siri Shortcuts get the current labels on a file? I’d like to have a single siri shortcut to essentially toggle the green tag/label on a file. Thanks

Hi @vincent_ardern

Yes if all you want is toggle Green, Shortcuts has you covered:

Cheers

Seb

Hi @sebastienkb i was hoping to have a single shortcut that would essentially do:

IF file is already tagged with green, then remove tag, ELSE tag with green

So I’ve found that Toolbox Pro does have a “tag files” action. The info inside Siri Shortcuts for that specific action implies that you can only set tags. However, the documentation inside the toolbox Pro app shows that there are actually 4 modes. GET, Set, Remove, and Remove All. I don’t think this will work on macOS but it’s basically an answer to my original question as far as iOS is concerned.

I see. I had done this years ago but only managed to make it work with the command line, using the tag command. Mixing a few CLI tricks I could get something working with that in Shortcuts. I didn’t find a way to do this either with Shortcuts or AppleScript natively.

This is a version 1 it has one flaw: it doesn’t propagate the tags like Finder does.
In Finder, when you have at least 1 item in Green, all other items become Green, but if all items were Green, all Green tags are cleared.

Instead, in this Shortcut what was off becomes on, and what was on becomes off. That’s for a version 2, somewhere later…

https://www.icloud.com/shortcuts/d464f98067ea428593bc59bfd3690aa0

Here’s a shortcut that toggles the green label on and off for a file passed to it.

It used to be you could only have one label, but in one of the OS revisions, this was changed to allow multiple labels. You can set a label on with AppleScript, or set all labels off - the AppleScript never caught up with the multi-label behaviour. As a reuslt I’ve gone the long way round and checked the state of all labels, toggled the state for the green label (label #6), removed all labels, and then reapplied using the states and the new green label toggled state. This means that when you have multiple labels on a file, it will keep those other labels in place and still toggle the green label.

Since Shortcuts lets you run AppleScript, this is bundled into a single script step that takes a file’s path from the shortcut input. I’ve set the shortcut to appear as a quick action in Finder so you can test it.

Hope that helps.


Are you are using a third-party command line tool alongside this Shortcut? It isn’t mentioned as a requirement, and I don’t seem to have a native tag command in macOS 12.5.1. I’ve used this tag command in the past, so I’m wondering if you might have used that one.

I was not aware of it but you’re right, tag was tucked away in my brew list. I assumed it was an Apple thing!

My memory is coming back to me and I was actually thinking of SetFile, but it doesn’t work for this thread as it doesn’t deal with tags. Back then I was using it to make files (in)visible. I think I was using that command before tags existed in Mac OS X. So all things considered, I’m a tag noob.

EDIT: I didn’t read thoroughly, thanks for your explanation in your previous post.
How does your AppleScript work its way to guess what “Green” is ? Is it the “6” index when calling? While it does work, I’m unable to understand how the code actually grabs Green and toggles it.

Unless you’re using macOS Ventura and there’s been an update to AppleScript to allow this, I don’t think what you’ve described is going to happen. I’m using macOS Monterey, and in this macOS version and every version prior to this in which label index has been a property of a disk item in Finder, it has only ever been able to store a single (unary) integer value. Assigning a new value to a disk item’s label index property overwrites whatever value it previously held.

Even when Finder principally assigned labels to its disk items, AppleScript was only ever able to retrieve the most-recently assigned label in cases where a disk item has multiple labels assigned to it. When assigning labels through AppleScript, it overwrote all pre-existing labels to leave only the one being assigned in their place.

However, nowadays, Finder uses a tags, which are similar to labels, but can have names outwith the recognised list of label colours, e.g. “work”, “important”. If a tag’s name happens to also be one of the recognised list of label colours, then the tag is coloured appropriately. This does not, however, equate to it being a label of that colour, although the most-recently assigned tag with a named colour is retrievable via the label index property in AppleScript.

I’m wondering if, during your testing of your Shortcut, you might have been setting and unsetting the green label in isolation of whatever pre-existing tags were also present, therefore ultimately manipulating the entity that was not only the most recent addition to the set of tags, but also the only one assigned by way of AppleScript and thus making it definitively a label.

1 Like

Potentially. I can’t recall every variation I tested last night. I’ll give it another set of tests after I finish work today.

If the getting of a specific label state is limited to the most recently set value, then that is definitely going to throw a spanner in the works as I would not be able to know the order they were applied. I will be a little surprised if I happened to coincidentally set the labels in sequence every time such that the sequential checks just happened to work, but stranger coincidences have happened in testing before. Certainly worth me doing another batch of testing by the sounds of it.

Finally got some time to test it only working on the most recently updated label (rather than the set of labels) today.

The following test did indeed fail, the fourth step should have removed the green label but did not.

  1. File has no labels → Labels: {}
  2. Run “Toggle Green Label” → Labels: {Green}
  3. Manually add orange label via Finder → Labels: {Green, Orange}
  4. Run “Toggle Green Label” → Labels: {Green, Orange}

Here’s an AppleScript handler that can hopefully serve as a replacement for the one in the shortcut you made. I don’t have time enough to download, edit, test, and share the shortcut right now, but I might be able to do so later in the week.

use framework "Foundation"
use scripting additions
--------------------------------------------------------------------------------
property inserting : 1
property deleting : -1
property toggling : 2
property nothing : -2
--------------------------------------------------------------------------------
to mutateFileTags at filepath by doing : -2 given tags:tags as list : {}
		script array
				property labels : the valueForKey_(my NSURLTagNamesKey) ¬
						of (resourceValuesForKeys_error_([my NSURLTagNamesKey], 0) ¬
						of the fileURLWithPath_(filepath) of my NSURL)
				property array : my (NSSet's setWithArray:labels)
				property list : mutableCopy() of the array
				property action : a reference to my [add_, toggle_, nothing_, remove_]
				
				to add:(list)
						local xs
						tell my list to addObjectsFromArray:xs
						return allObjects() in my list as list
				end add:
				
				to remove:(list)
						local xs
						tell my list to removeObjectsInArray:xs
						return allObjects() in my list as list
				end remove:
				
				to toggle:(list)
						local xs
						set xs to my (NSSet's setWithArray:xs)'s mutableCopy()
						tell my list to minusSet:xs
						tell xs to minusSet:array
						tell my list to unionSet:xs
						return allObjects() in my list as list
				end toggle:
				
				on nothing:{}
						return labels as list
				end nothing:
				
				property mutation : item doing of action as script
		end script
		
		set tags to array's mutation(tags)
		if doing = nothing then return tags
		
		tell the fileURLWithPath_(filepath) of my NSURL
				setResourceValue_forKey_error_(tags, my NSURLTagNamesKey, 0)
				getResourceValue_forKey_error_(reference, my NSURLTagNamesKey, 0)
				return result's first reference as list
		end tell
end mutateFileTags
--------------------------------------------------------------------------------

It’s a sort of all-in-one handler that requires a full, absolute, posix-format file path, and optionally accepts the desired operation one wishes to perform together with a list of tags relative to which the operations take place. So:

To add the labels Purple and Yellow to those already existing:

mutateFileTags at "/path/to/file" by inserting given tags:{"Purple", "Yellow"}

To remove the labels Purple and Yellow if the existing label set contains either of these two:

mutateFileTags at "/path/to/file" by deleting given tags:{"Purple", "Yellow"}

To toggle existing labels against Purple and Yellow, so that any existing purple or yellow label is removed, while these same labels will be added should they not be assigned already, leaving any other labels unaffected:

mutateFileTags at "/path/to/file" by toggling given tags:{"Purple", "Yellow"} 

To simply enumerate the existing tags without changing them:

mutateFileTags at "/path/to/file"
1 Like