user4515110 user4515110 - 5 months ago 17
Swift Question

casting arrays returned by NSURL.getResourceValue in Swift

I have spent all day trying to get useable results from NSURL.getResourceValue for NSURLTagNamesKey in swift. The function should take the path name as a string and return an array of strings for the user tags. I have a version of this that works in Objective C, but have not been able to re-write in Swift.

This is the current version of the code:

func listTags(filePath:String)->[String]{
//convert path string to NSURL
let theURL : NSURL = NSURL.fileURLWithPath(filePath)!

//get tags for NSURL -- should be NSArray of NSStrings hiding in an AnyObject?
var tags : AnyObject?
var anyError: NSError?
tags = theURL.getResourceValue(&tags, forKey:NSURLTagNamesKey, error: &anyError)

//unwrap tags object? This part never works
let tagArray = tags! as [AnyObject]

//insert every item in tag array into results array as a String
var results = [String]()
for object in tagArray{
results.append(object as String)
}

return results
}


The code will compile but breaks when it tries to convert the AnyObject to any other type. I have tried every combination I can think of -- [AnyObject], [String], NSArray, with/without exclamation points and question marks.

Am on verge of giving up on Swift.

Answer

You're going to kick yourself...

The method getResourceValue:forKey:error returns a value - a Bool, indicating whether the container you passed in as the first argument has been populated. Unfortunately you're assigning the value of this boolean to tags - your container! - which means that whatever was passed in to this container by Cocoa is immediately over-written. This worked for me...

var tags : AnyObject?
var anyError: NSError?
var success = theURL.getResourceValue(&tags, 
                       forKey:NSURLTagNamesKey, 
                       error: &anyError)
if success {
    println("container contents \(tags as [String])") // -> [AutoLayout, Swift]
}