NSFileManager, enumeratorAtURL and pathsMatchingExtensions

Instead of using NSPredicate to filter directory enumeration of file extension.
There is a instance method: pathsMatchingExtensions
https://developer.apple.com/documentation/foundation/nsarray/1418275-pathsmatchingextensions?language=objc

Here is a example.

use framework "Foundation"
use scripting additions

set thePath to POSIX path of (path to desktop)
my filesMatchingExtensions:{"scpt", "pdf", "webarchive"} inPath:thePath

on filesMatchingExtensions:theExtList inPath:thePath
	set theURL to current application's |NSURL|'s fileURLWithPath:thePath
	set manager to current application's NSFileManager's defaultManager()
	set enumOptions to (current application's NSDirectoryEnumerationSkipsPackageDescendants as integer) + (current application's NSDirectoryEnumerationSkipsHiddenFiles as integer)
	set directoryEnumeratorAllObjects to (manager's enumeratorAtURL:theURL includingPropertiesForKeys:{} options:enumOptions errorHandler:(missing value))'s allObjects()
	return ((directoryEnumeratorAllObjects's |path|)'s pathsMatchingExtensions:theExtList) as list
end filesMatchingExtensions:inPath:

Hi.

Is this a legitimate alternative to …

return ((directoryEnumerator's valueForKey:("path"))'s …

… or just something which happens to work? (I realise that ‘directoryEnumerator’ is an array of URLs here, not an enumerator.)

Hi Nigel.

The variable maybe are little misleading it use allObjects() at end. It contains all the remaining objects of the enumerator https://developer.apple.com/documentation/foundation/nsenumerator/1417755-allobjects?language=objc

So you are right its a array of URL

Maybe directoryEnumeratorAllObjects is better variable :slight_smile:

Hi Fredrik.

I was actually questioning your use of |path| instead of valueForKey:(“path”).

Sorry I misunderstood…

I know from the examples I did long time ago with NSURL and learn from that exercise I could use
path to translate fileURL to POSIX path. If that is the correct way or not I do not know.
https://developer.apple.com/documentation/foundation/nsurl/1408809-path?language=objc

Its also possible to do things like this…

return (directoryEnumeratorAllObjects's fileURL)'s |description|() as text
	return (directoryEnumeratorAllObjects's absoluteURL)'s |description|() as text

Ex.
directoryEnumeratorAllObjects’s |path| works
directoryEnumeratorAllObjects’s |path|() do not… same for example for above.

Here is other example.

set a to {key1:1}
set d to current application's NSDictionary's dictionaryWithDictionary:a

return (d's valueForKey:"key1") as integer --> 1
return (d's key1) as integer --> 1
return (key1 of d) as integer --> 1

So this will also work…

return ((|path| of directoryEnumeratorAllObjects)'s ...

This thread reminded me of something Shane wrote in his book:

So, if I understand correctly, the first and second lines that begin with “(theFiles’s” in the following script are two different ways of accomplishing the same thing and both work as expected. It seems like the third line that begins with “(theFiles’s” should also work but it doesn’t, although |path|() does work in other circumstances.

use framework "Foundation"
use scripting additions

on getFiles(theFolder)
	set theFolder to current application's |NSURL|'s fileURLWithPath:theFolder
	set fileManager to current application's NSFileManager's defaultManager()
	set enumOptions to (current application's NSDirectoryEnumerationSkipsPackageDescendants as integer) + (current application's NSDirectoryEnumerationSkipsHiddenFiles as integer)
	set theFiles to (fileManager's enumeratorAtURL:theFolder includingPropertiesForKeys:{} options:enumOptions errorHandler:(missing value))'s allObjects()
	
	(theFiles's |path|) as list -- works OK
	(theFiles's valueForKey:("path")) as list -- works OK
	(theFiles's |path|()) as list -- unrecognized selector error
end getFiles

getFiles(POSIX path of (path to documents folder))

Ah yes. Thanks, peavine. It was worth reading that entire note again.