I’m working on the following script just as a matter of general interest. The script works as I want except that I want it to return URLs instead of paths. I thought this might be accomplished by changing NSURLPathKey to a resource key that returns a URL, but I couldn’t find anything that works.
As an alternative, I rewrote the section of the script that creates an array of dictionaries to separately add the resource key values and then the URL to the dictionary. This worked OK but was slow.
Can the following be made to work by changing NSURLPathKey to a resource key for NSURLs? Thanks for the help.
use framework "Foundation"
use scripting additions
--Set source folder to current user's Home folder
set theFolder to current application's NSHomeDirectory()
set theFolder to current application's |NSURL|'s fileURLWithPath:theFolder
--Get contents of source folder
set fileManager to current application's NSFileManager's defaultManager()
set folderContents to (fileManager's enumeratorAtURL:theFolder includingPropertiesForKeys:{} options:6 errorHandler:(missing value))'s allObjects() --option 6 skips hidden items and package contents
--Set variables to resource keys
set folderKey to current application's NSURLIsDirectoryKey
set regularFileKey to current application's NSURLIsRegularFileKey
set fileKey to current application's NSURLPathKey --returns path and works OK but I want URLs
--Create array of dictionaries with resource key values
set fileData to current application's NSMutableArray's new()
repeat with anItem in folderContents
(fileData's addObject:(anItem's resourceValuesForKeys:{folderKey, regularFileKey, fileKey} |error|:(missing value)))
end repeat
--Filter based on desired resource key
set thePredicate to current application's NSPredicate's predicateWithFormat_("%K == YES", folderKey)
# set thePredicate to current application's NSPredicate's predicateWithFormat_("%K == YES", regularFileKey)
(fileData's filterUsingPredicate:thePredicate)
return (fileData's valueForKey:fileKey) as list
I want the script to return an array of NSURLs, and, when coerced to a list, a list of file objects. I don’t understand how your suggestion would accomplish that.
BTW, there was an error in my script, and I’ve fixed that.
NSURL doesn’t have a resource for itself, but couldn’t you just add the URL to the fileData items and get the key for it? For example:
repeat with anItem in folderContents
set itemInfo to current application's NSMutableDictionary's new()
(itemInfo's setObject:anItem forKey:"URLKey") -- or whatever key name
(itemInfo's addEntriesFromDictionary:(anItem's resourceValuesForKeys:{folderKey, regularFileKey, fileKey} |error|:(missing value)))
(fileData's addObject:itemInfo)
end repeat
And then return (fileData's valueForKey:"URLKey"). Note that coercing to a list would result in AppleScript file items.
I had tried that approach but it was slow (at least compared with the approach that returned paths). I assume that the additional time is due to the time it takes to create the array of dictionaries. However, until I get the other version working, I can’t be sure of this.
It would seem a bit odd if NSURL had a resource for itself. Though, in the back of my mind, I seem to recall seeing that done.
use framework "Foundation"
use scripting additions
--Set source folder to current user's Home folder
set theFolder to current application's NSHomeDirectory()
set theFolder to current application's |NSURL|'s fileURLWithPath:theFolder
--Get contents of source folder
set fileManager to current application's NSFileManager's defaultManager()
set folderContents to (fileManager's enumeratorAtURL:theFolder includingPropertiesForKeys:{} options:6 errorHandler:(missing value))'s allObjects() --option 6 skips hidden items and package contents
--Set variables for resource keys
set folderKey to current application's NSURLIsDirectoryKey
set regularFileKey to current application's NSURLIsRegularFileKey
--Create array of dictionaries with resource key and URL values
set fileData to current application's NSMutableArray's new()
repeat with anItem in folderContents
set dictionaryOne to (anItem's resourceValuesForKeys:{folderKey, regularFileKey} |error|:(missing value))'s mutableCopy()
set dictionaryTwo to (current application's NSDictionary's dictionaryWithObject:anItem forKey:"URLKey")
(dictionaryOne's addEntriesFromDictionary:dictionaryTwo)
(fileData's addObject:dictionaryOne)
end repeat
--Filter based on desired resource key
set thePredicate to current application's NSPredicate's predicateWithFormat_("%K == YES", folderKey)
# set thePredicate to current application's NSPredicate's predicateWithFormat_("%K == YES", regularFileKey)
(fileData's filterUsingPredicate:thePredicate)
return (fileData's valueForKey:"URLKey") as list
BTW, I had some trouble getting the syntax to work correctly, so I took a minutely different approach than you suggest.
As you are using a loop anyway wouldn’t it be more efficient to do the filtering instantly in the loop?
Then you can add the current NSURL to the fileData array
And you can speed up the script a bit by including the keys in the includingPropertiesForKeys: parameter.
Something like this
use framework "Foundation"
use scripting additions
--Set source folder to current user's Home folder
set theFolder to current application's NSHomeDirectory()
set theFolder to current application's |NSURL|'s fileURLWithPath: theFolder
--Set variables for resource keys
set folderKey to current application's NSURLIsDirectoryKey
set regularFileKey to current application's NSURLIsRegularFileKey
set fileKey to current application's NSURLPathKey
--Get contents of source folder
set fileManager to current application's NSFileManager's defaultManager()
set folderContents to (fileManager's enumeratorAtURL:theFolder includingPropertiesForKeys:{folderKey, regularFileKey, fileKey} options:6 errorHandler:(missing value))'s allObjects() --option 6 skips hidden items and package contents
--Create array of dictionaries with resource key and URL values
set fileData to current application's NSMutableArray's new()
repeat with anItem in folderContents
set theResource to (anItem's resourceValuesForKeys:{folderKey, regularFileKey, fileKey} |error|:(missing value))
set theValue to (theResource's objectForKey:folderKey)
if theValue as boolean then
(fileData's addObject:anItem)
end if
end repeat
return fileData as list
By the way: NSURL has a property hasDirectoryPath to check if the URL represents a directory
I had previously run timing tests with Script Geek. and the approach you suggest took 47 milliseconds and the approach I use above took 60 milliseconds. So, I agree with what you say, but I like to try out different ways of doing stuff.
I had also previously run tests and including the keys in the includingPropertiesForKeys: parameter made absolutely no difference in the time it took for the script to run. I know this is counter intuitive but I spent a fair amount of time testing this with Script Geek.
It’s been a year or more since I ran the timing tests for including and not including the resource keys in the includingProperitesForKeys: parameter. Later today, I will rerun these tests and post the results.
on FileSystem_Convert_Objects_To_Files(fileSystemObjectList)
try
set fileSystemObjectList to (fileSystemObjectList) as list
repeat with currentIndex from 1 to length of fileSystemObjectList
set item currentIndex of fileSystemObjectList to (item currentIndex of fileSystemObjectList) as «class furl»
end repeat
return fileSystemObjectList
on error errorText number errornumber partial result errorResults from errorObject to errorExpectedType
error "<FileSystem_Convert_Objects_To_Files>" & space & errorText number errornumber partial result errorResults from errorObject to errorExpectedType
end try
end FileSystem_Convert_Objects_To_Files
So, used in your original post…
--Running under AppleScript 2.8, MacOS 15.7.5
use framework "Foundation"
use scripting additions
--Set source folder to current user's Home folder
set theFolder to ((current application's NSHomeDirectory()) as text) & "/Desktop"
set theFolder to current application's |NSURL|'s fileURLWithPath:theFolder
--Get contents of source folder
set fileManager to current application's NSFileManager's defaultManager()
set folderContents to (fileManager's enumeratorAtURL:theFolder includingPropertiesForKeys:{} options:6 errorHandler:(missing value))'s allObjects() --option 6 skips hidden items and package contents
FileSystem_Convert_Objects_To_Files(folderContents)
-->>"{file "Macintosh HD:Users:UserNameGoesHere:Desktop:IMG_3861.psd", file "Macintosh HD:Users:UserNameGoesHere:Desktop:IMG_3861.psb", file "Macintosh HD:Users:UserNameGoesHere:Desktop:Screenshot 2026-05-18 at 9.37.46 AM.png", file "Macintosh HD:Users:UserNameGoesHere:Desktop:sort:", file "Macintosh HD:Users:UserNameGoesHere:Desktop:sort:untitled folder:", file "Macintosh HD:Users:UserNameGoesHere:Desktop:sort:untitled folder:Screenshot 2026-05-14 at 5.58.21 PM.png", etc
on FileSystem_Convert_Objects_To_Files(fileSystemObjectList)
try
set fileSystemObjectList to (fileSystemObjectList) as list
repeat with currentIndex from 1 to length of fileSystemObjectList
set item currentIndex of fileSystemObjectList to (item currentIndex of fileSystemObjectList) as «class furl»
end repeat
return fileSystemObjectList
on error errorText number errornumber partial result errorResults from errorObject to errorExpectedType
error "<FileSystem_Convert_Objects_To_Files>" & space & errorText number errornumber partial result errorResults from errorObject to errorExpectedType
end try
end FileSystem_Convert_Objects_To_Files