In my app (Find Any File), I am querying the Finder for the currently selected or frontmost finder window.
Here’s the plain AppleScript code that always works:
tell application "Finder"
with timeout of 0.1 seconds
set res to selection
if res is {} then
set res to URL of target of front window
else
set res to URL of first item of res
end if
return res
end timeout
end tell
Now, I’m trying to implement the same in ObjC via the ScriptingBridge.h interface.
Here’s the code I use:
static FinderApplication *finder = nil;
if (finder == nil) finder = [SBApplication applicationWithBundleIdentifier:@"com.apple.finder"];
[finder setTimeout:6]; // 100ms (unit is ticks)
// Is something actively selected?
SBElementArray *selection = [[finder selection] get];
if (selection.count > 0) {
NSArray<NSString*> *urlStrings = [selection arrayByApplyingSelector:@selector(URL)];
for (NSString *s in urlStrings) {
NSURL *url = [NSURL URLWithString:s];
if (url.absoluteString.length > 0) {
[(NSMutableArray*)result addObject:url];
}
}
} else {
// Fallback: Take the front window as the selected item
SBElementArray *windows = [finder FinderWindows];
for (FinderFinderWindow *window in windows) {
@try {
FinderItem *target = [window.target get];
if (target) {
NSString *urlStr;
NSDictionary *p = [target properties];
if (p == nil) {
urlStr = [target URL]; // Caution: using "[target URL]" works often but raises exc if it's the root dir!
} else {
urlStr *str = p[@"URL"];
}
...
This usually works.
The problem is when the user has opened a folder on a network (SMB or AFP) server in Finder (and not selected an item in the window). In that case, [target properties]
gives nil, as does [target URL]
. (Tested on macOS 10.13 and 11.4)
Any idea why this would fail, when the plain AppleScript, which basically does the same, works even in this special case?