Getting the default app does not work for certain apps.

I’m using the following app to test a routine to determine the default app that will start, based on the extension of a data file. The routine will not return my app as the default name even with the association being set by hand. The routine does, however, work for the std apps shipped with Mac Mojave.

Perhaps someone has seen this behaviour and suggest a solution?


use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

on run
	
	-- Allow the user to change it
	set theResponse to display dialog "Default 'Buddy' (aka metadata) file extension:" default answer "meta" with icon note buttons {"Ok"} default button "Ok"
	set theExt to (text returned of theResponse) as string
	
	-- Determine the default app for theFile...
	set theDefaultApp to getDefaultApp(theExt)
	
	display dialog theDefaultApp
	
end run

-- -------------------------------------------------------------
-- getDefaultApp(theFileExt)
-- Return the default app for a specified extension.
-- 	Based on @ShaneStanley's script & enhancements (2017-11-26)
--	http://forum.latenightsw.com/t/how-do-i-get-the-default-app/830/2
-- Consider using actual file to get extension rather than a dummy one.	
-- 	theFileExt		: The extension of a file as a string.
-- 	return			: The default application as text.
-- ------------------------------------------------------------
on getDefaultApp(theFileExt)
	
	local theFilename -- The filename of a temporary file.
	local theWorkspace -- The workspace of the current App.
	local NSCurrentApp -- The current App.
	local NSAppURL -- The URL for the default App.
	local NSResult -- The result of getting the resource value of the default App.
	local NSAppName -- The filename of the default App.
	local NSError -- The error code for getting the resource value of the default App.
	-- Define a temporary filename, with the target extension, to be created in the temporary directory.
	set theFilename to (POSIX path of (path to temporary items)) & "temp." & theFileExt
	-- Determine the current application.
	set NSCurrentApp to current application
	--- Create the temporary file.
	NSCurrentApp's NSFileManager's defaultManager()'s createFileAtPath:theFilename |contents|:(missing value) attributes:(missing value)
	-- Determine the workspace for the current application.
	set theWorkspace to NSCurrentApp's NSWorkspace's sharedWorkspace()
	-- Get URL of default App for the temporary file using "URLForApplicationToOpenURL"
	-- - (NSURL *)URLForApplicationToOpenURL:(NSURL *)url;
	-- The URL of the default app that would open the specified url. 
	-- Returns nil if no app is able to open the url, or if the file url does not exist.
	-- This is the programmatic equivalent of double clicking a document in the Finder.
	-- It is safe to call this method from any thread of your app.
	set NSAppURL to theWorkspace's URLForApplicationToOpenURL:(NSCurrentApp's |NSURL|'s fileURLWithPath:theFilename)
	if NSAppURL is not (missing value) then
		--- Get the Filename of the default App.
		set {NSResult, NSAppName, NSError} to NSAppURL's getResourceValue:(reference) forKey:(NSCurrentApp's NSURLLocalizedNameKey) |error|:(reference)
		--- Convert the name of the default App to text.
		set theappName to NSAppName's stringByDeletingPathExtension() as text
		-- Return the name of the default App as text.
	else
		set theappName to ("#Error: Missing NSAppURL for: " & theFileExt) as text
	end if
	return theappName
end getDefaultApp

Is your app in /Applications or similar?

It was on the desktop, Shane. I placed it in the Applications directory and it works.

If I drag it to the desktop, it makes an alias and then it will run from there.

I feel a bit embarrassed to ask… Why do such applications need to be in the Applications directory to run and yet I’ve others that run directly from the desktop?

They run fine anywhere. But the daemon that maintains the database of what apps can open what documents only scans the various Applications directories, and their subdirectories.

When you launch apps located elsewhere this information should also be extracted for them, but it’s a less reliable thing when the applications themselves are regularly changing. AppleScript applications are unusual, in that most applications are only updated relatively infrequently.

Just moving an app into an Applications directory temporarily is probably enough, at least until you next change its relavant Info.plist entries.

Thank you for the explanation. It makes sense, and the solution does work but is not something I’ve heard before. I have heard of people forcing a launch services scan, but never put it together with this issue. The apparent lack of determinism that this (scan frequency and priority location) could introduce in the functioning of an app is a bit worrisome.

Suffice to say, the issue is as solved as it is ever likely to be. Thank you, again.