AppKit Advice / Get Active Font List

I could use a pointer on using the AppKit framework in a script.

I found the following code that seems to work well for getting a list of fonts that are currently enabled/active:

use framework "AppKit"
set fontNames to (current application's NSFontManager's sharedFontManager's availableFonts) as list

However, I’m finding that AppKit is preventing another part of the script from running correctly. It runs right if I remove the above code and set fontNames to a list of font names manually.

Is there a way to invoke the use of AppKit just for gathering the font names and then unload/deactivate/disable it for the rest of the script? Or maybe another way of getting the name of only enabled font names that doesn’t use AppKit?

Thanks for any suggestions,

Mary

I’m guessing that the other part of the script that doesn’t run with the appkit call is in a scripting additions.

Try adding this to your script:

use scripting additions
1 Like

This issue arose a few years back and, if I remember correctly, the solution was to run the ASObjC code in a script object. I’m not sure if the syntax of the following is correct, but it does return the font name:

set theFonts to getFonts()

on getFonts()
	script o
		use framework "AppKit"
		on getFontList()
			return (current application's NSFontManager's sharedFontManager's availableFonts) as list
		end getFontList
	end script
	return o's getFontList()
end getFonts
3 Likes

Thanks, estockly. I use Script Debugger, which automatically puts “using scripting additions” at the top of any new script. I appreciate the suggestion, though!

Wow, peavine, thank you so much for your help with this! I never would have figured that out on my own.

Tested and seems to do just what I want without killing other parts of the script.

Thank you again!

Fredrik71. The only substantive change I can find in your code suggestion is the addition of the parentheses at the end of the availableFonts property. This is an issue discussed by Shane on page 35 of his ASObjC book, where he explains that getting a property without using parentheses causes the script to use key-value coding. Shane’s final thoughts on this topic are:

So rather than using just the property name without parentheses and doing coercions where necessary, and trying to remember to include the parentheses whenever the object could be a member of a class that implements valueForKey: in its own way, I generally find it simpler to include the parentheses each time. If you see code that doesn’t, don’t worry — it may well work fine. Conversely, if your code is not working as you expect, this is an issue you should check.

The NSFontManager class does not appear to implement its own valueForKey coding, and both approaches return an array of NSStrings, which do not require any special coercions. So, either approach seems perfectly acceptable to me, although I generally follow Shane’s advice and use parentheses. The following may be an example of a situation where I might intentionally omit the parentheses:

use framework "Foundation"
set textNumber to current application's NSString's stringWithString:"1"
set integerNumber to textNumber's integerValue() --> 1
set integerNumber to textNumber's integerValue --> (NSNumber) 1