skip to Main Content

I am creating my first project for MacOs.
I have to work on files in a folder. My goal is to check these files and see which elements have a red tag applied via Finder.
I am literally going crazy because the code cannot recognise the images with the red tag.

This is the function I have written.

 func isFileTaggedRed(at fileURL: URL) -> Bool {
        do {
            let resourceValues = try fileURL.resourceValues(forKeys: [.labelColorKey])
            if let labelColor = resourceValues.labelColor, labelColor == .red {
                return true
            }
        } catch {
            print("Error retrieving resource values for file: (error)")
        }
        
        return false
    }

This is the code in the ViewController

for imageUrl in imageUrls {
            if isFileTaggedRed(at: imageUrl) {
                print("Skipping red tagged image: (imageUrl.lastPathComponent)")
                continue
            }else{
                print("not tagged")
            }
        }

file info

2

Answers


  1. I haven’t used labelColorKey before. It looks like the labelColor you get back is an NSColor. Colors are tricky in a color-managed system like MacOS. The color may be a shade of red but not the exact color you want. I would suggest logging the RGB values of your returned colors with NSColor.getRed(_:green:blue:alpha:). You’re probably getting back a color that’s close to, but not exactly equal to .red.

    You might need to add code that checks to see if the RGB values are within a "wiggle room" range of .red (say each component is within .01 of the target color.)

    Edit:

    I just tried it, and when I added a red label to a file, I got back an NSColor that logs as NSCalibratedRGBColorSpace 0.980484 0.382818 0.347662 1

    That will look red, but not fully saturated red.

    Note that NSColor.red logs as sRGB IEC61966-2.1 colorspace 1 0 0 1 (100% red and no green or blue.)

    Furthermore, when I look at a file with a red label, it does look like a slightly washed out red, not pure red.

    Edit #2:

    The code I used (in a command line tool) is as follows:

    func fileColor(at fileURL: URL) -> NSColor? {
           do {
               let resourceValues = try fileURL.resourceValues(forKeys: [.labelColorKey])
               if let labelColor = resourceValues.labelColor {
                   return labelColor
               }
           } catch {
               print("Error retrieving resource values for file: (error)")
               return nil
           }
           
           return nil
       }
    
    let path = "~/Documents/RedFile.rtf"
    let fixedPath = NSString(string:path).expandingTildeInPath
    let fileURL = URL(filePath: fixedPath)
    
    if let fileColor = fileColor(at: fileURL) {
        print("File color returned is (fileColor)")
    } else {
        print("Could not load file.")
    }
    
    Login or Signup to reply.
  2. I don’t know if there is an easier way to accomplish what you need but you can get the fileUrl tagNames and check if it contains "Red"


    extension URL {
        var isFileTaggedRed: Bool {
            tagNames.contains("Red")
        }
        var tagNames: [String] {
            (try? resourceValues(forKeys: [.tagNamesKey]))?.tagNames ?? []
        }
    }
    

    Usage:

    import Cocoa
    
    class ViewController: NSViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let folderUrl = FileManager.default.urls(for: .desktopDirectory, in: .userDomainMask).first!
                .appendingPathComponent("untitled folder", isDirectory: true)
    
            let files = try! FileManager.default.contentsOfDirectory(at: folderUrl, includingPropertiesForKeys: nil)
    
            if let fileUrl = files.first {
                print("isTaggedRed:", fileUrl.isFileTaggedRed)
            }
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search