Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I retrieve all available Finder tags?

I'm trying to retrieve a list of all the available Finder tags.

I found NSWorkspace().fileLabels, which does return an array, but only an array of the tag colours, not the tags themselves:

print(NSWorkspace.shared().fileLabels) // prints ["None", "Gray", "Green", "Purple", "Blue", "Yellow", "Red", "Orange"]

Which as you can see is not even all the default tags, it's missing Home, Work and Important, and obviously doesn't have any of the custom ones that I created. It looks like it's just the nice names that go with fileLabelColors.

I found NSMetadataQuery for actually searching for things, but how do I get a list of all the tags I have created in the Finder?

like image 835
mhurron Avatar asked Oct 18 '22 18:10

mhurron


1 Answers

NSWorkspace.shared().fileLabels only returns the system tags that were available when the user account was created (the default system tags).

There's unfortunately no API in macOS to retrieve the tags that you have created yourself in the Finder.

The solution is to parse the ~/Library/SyncedPreferences/com.apple.finder.plist:

func allTagLabels() -> [String] {
    // this doesn't work if the app is Sandboxed:
    // the users would have to point to the file themselves with NSOpenPanel
    let url = URL(fileURLWithPath: "\(NSHomeDirectory())/Library/SyncedPreferences/com.apple.finder.plist")
    let keyPath = "values.FinderTagDict.value.FinderTags"
    if let d = try? Data(contentsOf: url) {
        if let plist = try? PropertyListSerialization.propertyList(from: d, options: [], format: nil),
            let pdict = plist as? NSDictionary,
            let ftags = pdict.value(forKeyPath: keyPath) as? [[AnyHashable: Any]]
        {
            return ftags.flatMap { $0["n"] as? String }
        }
    }
    return []
}

let all = allTagLabels()
print(all)

This gets all Finder tags labels.

You can also select only the custom tags (ignore the system ones):

func customTagLabels() -> [String] {
    let url = URL(fileURLWithPath: "\(NSHomeDirectory())/Library/SyncedPreferences/com.apple.finder.plist")
    let keyPath = "values.FinderTagDict.value.FinderTags"
    if let d = try? Data(contentsOf: url) {
        if let plist = try? PropertyListSerialization.propertyList(from: d, options: [], format: nil),
            let pdict = plist as? NSDictionary,
            let ftags = pdict.value(forKeyPath: keyPath) as? [[AnyHashable: Any]]
        {
            return ftags.flatMap { tag in
                if let n = tag["n"] as? String,
                    tag.values.count != 2
                {
                    return n
                }
                return nil
            }
        }
    }
    return []
}
like image 118
Eric Aya Avatar answered Oct 21 '22 00:10

Eric Aya