obtuse error message when trying to add a tag to a file in the finder.

Hi, caught in a loop of unhelpful error messages. Been trying to find a code example to follow, apparently that is not a thing anymore. the docs... for over 20 years now are only half finished. So Im here in the forums looking for guidance.

I am trying to set a resource for an existing file URL. the intention is to add a tag to the file. Nothing onerous. Should be easy. Getting the list of tags WAS easy.

here's the code as I have it:

func setItemTags(atURL:URL, tags: [String]){
        do {
            try atURL.setResourceValue(tags, forKey: .tagNamesKey)
        } catch let error as NSError {
            print(error)
        }
    }

I get an error that says: Argument type '[String]' expected to be an instance of a class or class-constrained type

ok. seems pretty straight forward, the Array (which is what I get from acquiring the resources... so this doesn't make much sense at all, but whatever.) needs to be a class. clearly it's a Holdover from Obj-c. And it needs to be an NSArray. I SHOULD be able to bridge to an NSArray by replacing 'tags' with 'NSArray(array: tags)'

but that doesn't work at all. I get a different error. 'setResourceValue(:forKey:)' is unavailable: Use struct URLResourceValues and URL.setResourceValues(:) instead

So no error message is really telling us anything. no matter how much I try, I can't just materialize the answer out of thin air.

what I really need is a single example of how to properly use the 'steresourceValue' function of URL, to set the .tagNamesKey. I am astonished that this is not documented anywhere.*

*I have found ancient examples of this, which is now deprecated by changes to swift, and is only useful as a source of confusion.

Answered by mikeyh in 708598022

Try something like this:

try (atURL as NSURL).setResourceValue(tags, forKey: .tagNamesKey)

Might be a defect in the Swift overlay bridging of URL to NSURL.setResourceValue(_:forKey:)

Accepted Answer

Try something like this:

try (atURL as NSURL).setResourceValue(tags, forKey: .tagNamesKey)

Might be a defect in the Swift overlay bridging of URL to NSURL.setResourceValue(_:forKey:)

The modern way to set a resource value is with code like this:

var url = atURL
var rv = URLResourceValues()
rv.contentModificationDate = Date()
try url.setResourceValues(rv)

Changing that middle line to this:

rv.tagNames = tags

fails with the error Cannot assign to property: 'tagNames' is a get-only property. If you look at the docs for the tagNames property you’ll see it declared like this:

var tagNames: [String]? { get }

It really is read-only. Which is weird because the corresponding Objective-C declaration makes it clear that the property is read/write:

FOUNDATION_EXPORT NSURLResourceKey const NSURLTagNamesKey 
API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos);	
// The array of Tag names (Read-write, value type NSArray of NSString)

This is clearly a bug in the Swift overlay and I encourage you to file it as such. Please post your bug number, just for the record.

In the meantime, doing this via NSURL, as suggested by mikeyh, is a perfectly reasonable workaround.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Oh, I see from that other thread there there’s already a bug on file about this (FB8910801). I just took a quick look and there’s no sign of this being fixed )-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

If the read only URLResourceValues.tagNames is not intentional is this two defects?

  • get-only URLResourceValues.tagNames
  • URL bridging to NSURL.setResourceValue(_:forKey:) error Argument type '[String]' expected to be an instance of a class or class-constrained type

is this two defects?

No, just the one.

If we fixed the first then the NSURL stuff would be irrelevant and thus the fact that you have to jump through some Swift to Objective-C interoperability hoops wouldn’t matter.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

obtuse error message when trying to add a tag to a file in the finder.
 
 
Q