Hi folks.
Can anyone with a Mavericks system or a long memory tell me if a script containing ASObjC in its source code can be compiled and run in Mavericks if it doesn’t actually try to execute the ASObjC stuff?
Background:
The scriptable genealogy software GEDitCOM II has an Extensions menu from which AppleScripts and its own “extensions” can be run. Three of the supplied extensions contain scripts in .applescript form which get data from the current GEDitCOM II document and compose beautifully styled reports in new Pages documents. They were written for Pages '09 and are useless to anyone stuck with the essentially unscriptable Pages 5. For my own education, I’ve adapted them to style the text in-house using ASObjC and to paste it into Pages when its complete. The adaptations work with both Pages '09 and Pages 5, produce exactly the same results (but without headers and footers), and are several times as fast as the originals.
I don’t know if I’ll bother offering them to the “GEDitCOM II community”, but they’re designed to be self-contained .applescripts like the originals, with the option of being useable in Mavericks if the user consents to the installation of the necessary library bundle. In Yosemite or later, a handler at the bottom of each script instances a script object containing the ASObjC code and this is used as a library. In Mavericks (or if a certain property value’s changed in the script), a different handler looks for the library in the user’s Script Libraries folder and, if it exists, employs a trick to ‘use’ it at that point. If the library’s not found, and the user consents, the script instances its on-board library, saves it as a script bundle in the Script Libraries folder, adds a suitable “Info.plist” file, and then 'use’s the bundle. It all works brilliantly when tested in El Capitan, and no doubt works in Yosemite too, but I’ve no idea if it actually works in Mavericks!
Below is a test script based on what happens in the adaptations. What I’d like to know is, in Mavericks:
- Does the script say anything?
- Does it successfully install a library bundle in the user’s Script Libraries folder?
- Does the trick to “use” the library work?
- Is the library viable when loaded that way? (Does the script display an upper-cased string?)
use AppleScript version "2.3.1"
use scripting additions
test()
on test()
say "Well. I'm running."
delay 1
-- Check that the library we want to use is in the user's Script Libraries folder (if that exists).
set pathToScriptLibrariesFolder to (path to library folder from user domain as text) & "Script Libraries:"
set pathToTestLib to pathToScriptLibrariesFolder & "NG's Test Lib.scptd"
tell application "System Events" to set libFound to (disk item pathToTestLib exists)
-- If not, create it from the on-board library code.
if (not libFound) then
say "I can't find the library bundle, so I'll attempt to install one."
delay 1
-- Create the Script Libraries folder if it doesn't already exist.
do shell script ("mkdir -p " & (quoted form of POSIX path of pathToScriptLibrariesFolder))
-- Instance this script's on-board library and save it as a script bundle (courtesy of the ".scptd" name extension) in the folder.
store script getLib() in file pathToTestLib
-- Edit (or on my system create) the bundle's Info.plist file, including an entry enabling the bundle for ASObjC in Mavericks.
set plistText to "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.ScriptEditor.id.ReportsToPagesOutputLib</string>
<key>CFBundleName</key>
<string>ReportsToPagesOutputLib</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>OSAAppleScriptObjCEnabled</key>
<true/>
</dict>
</plist>
"
set fRef to (open for access file (pathToTestLib & ":Contents:Info.plist") with write permission)
try
set eof fRef to 0
write plistText as «class utf8» to fRef
end try
close access fRef
say "OK so far, I think."
delay 1
end if
say "I'm going to try loading the library."
delay 1
-- Con the Libraries system into loading the library only now (instead of when the script's compiled).
set lib to lib of (run script "script
use lib: script \"NG's Test Lib\"
end script")
say "And now to try using it."
tell lib to |uppercase|("It works! :)")
display dialog result buttons {"OK"} default button 1
say "Don't forget to delete the test library bundle when you've finished testing."
tell application "Finder"
reveal file pathToTestLib
activate
end tell
end test
on getLib()
script -- A script object containing an ASObjC routine for testing.
use AppleScript version "2.3.1"
use framework "Foundation"
on |uppercase|(txt)
return (current application's class "NSString"'s stringWithString:(txt))'s uppercaseString() as text
end |uppercase|
end script
return result
end getLib
Edit: Terminology correction in the query.