I’m working on a handler that converts any type of filesystem object reference into an NSURL.
Requirements:
•Accept any single filesystem object [alias, file, nsurl, posix file, posix path, hfs path] returning a single NSURL.
•Accept [list or NSArray] of any combination of [aliases, files, nsurls, posix files, posix paths, hfs paths] returning an NSArray of NSURLs.
I would greatly appreciate if anyone with more ASOBJC chops than I would take a critical look at this handler and offer any suggestions! Code or logic optimizations, either would be awesome. I wouldn’t be surprised if there is a completely different methodology I could be using here. TIA!
I try to keep code to a minimum in handlers, but processing efficiency for this handler is extremely important to me as it’s called by numerous other handlers, and often repeatedly. Handling filesystem objects that are already NSURLs is crucial as this condition occurs most frequently, so at the beginning of the handler I test for a single NSURL parameter and immediately return it. Same for NSArrays of NSURLs.
For a more intense test, change “path to the desktop folder” to “path to the home folder”. 12.39 seconds here ( old intel box / Tahoe ) for 320,629 items.
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
set fileSystemObjectList to FileSystem_List_Contents(path to the desktop folder)
set NSURLList to FileSystem_Convert_Objects_To_NSURLs(fileSystemObjectList)
set NSURLListLength to (NSURLList's valueForKey:"@count") as integer
on FileSystem_Convert_Objects_To_NSURLs(fileSystemObjectList)
--THIS HANDLER IS USED EXTENSIVELY IN OTHER HANDLERS. ANY OPTIMIZATIONS HERE WOULD BE VERY VALUABLE
try
set singularParameter to true
--IF FILESYSTEMOBJECTLIST IS A SINGLE NSURL THEN RETURN IT UNMODIFIED
try
if ((fileSystemObjectList's isKindOfClass:(current application's NSURL))) then
return fileSystemObjectList
end if
end try
--IF PARAMETER IS ARRAY OF NSURLS THEN RETURN IT UNMODIFIED
try
if (fileSystemObjectList's isKindOfClass:(current application's NSArray)) then
set {parameterIsNSArray, singularParameter} to {true, false}
set classNames to (fileSystemObjectList's valueForKey:"className") --as list
set classNamesSet to (current application's NSSet's setWithArray:classNames)
set classNames to (classNamesSet's allObjects()) as list
if length of classNames is 1 and (item 1 of classNames) is "NSURL" then return fileSystemObjectList
end if
on error
set parameterIsNSArray to false
end try
--CONVERT APPLESCRIPT LIST PARAMETERS TO NSARRAYS
if class of fileSystemObjectList is in {list} then
set fileSystemObjectList to (current application's NSArray's arrayWithArray:fileSystemObjectList)
set singularParameter to false
end if
--CONVERT SINGLE ITEM PARAMETERS TO SINGLE ITEM NSARRAYS
if singularParameter then set fileSystemObjectList to (current application's NSArray's arrayWithObject:fileSystemObjectList)
--REGARDLESS OF INPUT PARAMETER fileSystemObjectList SHOULD NOW BE AN NSARRAY
set fileSystemObjectListLength to (fileSystemObjectList's valueForKey:"@count") as integer
repeat with currentIndex from 1 to fileSystemObjectListLength
set fileSystemObject to item currentIndex of fileSystemObjectList
try
if ((fileSystemObject's isKindOfClass:(current application's NSURL))) then
--SKIP IT
else --NOT AN NSURL. CONVERT IT.
try
set fileSystemObject to POSIX path of fileSystemObject
on error
try
tell application "System Events"
set fileSystemObject to POSIX path of ((path of disk item (fileSystemObject as string)) as alias)
end tell
on error
set fileSystemObject to POSIX path of (fileSystemObject as alias)
end try
end try
set fileSystemObject to (current application's class "NSURL"'s fileURLWithPath:fileSystemObject)
set item currentIndex of fileSystemObjectList to fileSystemObject
end if
end try
end repeat
if singularParameter then return item 1 of fileSystemObjectList
return fileSystemObjectList
on error errorText number errornumber partial result errorResults from errorObject to errorExpectedType
error "<FileSystem_Convert_Objects_To_NSURLs>" & space & errorText number errornumber partial result errorResults from errorObject to errorExpectedType
end try
end FileSystem_Convert_Objects_To_NSURLs
on FileSystem_List_Contents(folderObject)
--FULL RECURSIVE LISTING NOT INCLUDING INVISIBLES OR CONTENTS OF PACKAGES
try
set folderObject to FileSystem_Convert_Objects_To_NSURLs(folderObject)
set theEntireContents to ((current application's NSFileManager's defaultManager's enumeratorAtURL:folderObject includingPropertiesForKeys:{} options:6 errorHandler:(missing value))'s allObjects())'s mutableCopy()
return theEntireContents
on error errorText number errornumber partial result errorResults from errorObject to errorExpectedType
error "<FileSystem_List_Contents>" & errorText number errornumber partial result errorResults from errorObject to errorExpectedType
end try
end FileSystem_List_Contents