[solved] Having trouble getting the URL property via ScriptingBridge

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?

Ugh, I can’t believe it - it’s because of the timeout. 100ms is too short. If I change it from 6 to 30, it works.

One would think that the information is cached by the Finder and therefore shouldn’t take any time - especially not more time just because it’s on a remote volume. But that’s what appears to happen: Finder appears to go “live” on the volume to double check the URL is still valid.

Sigh.

That you continue to express such optimism speaks highly of your character :wink:.

5 Likes