2

As part of an automation workflow I'd like to be able to store a reference to an applescript object inside an NSMutableDictionary. This is done, in effect, to be able to use variable variable names. Keeping an NSAppleScript instance alive, I'd then be able to refer back to previous results and continue from where I left off.

Concretely, I'd like to store a Presentation object (Microsoft PowerPoint) inside an NSMutableDictionary.

use framework "Foundation"
property memory : null
set memory to current application's NSMutableDictionary's dictionary()

-- function to get a ref to a presentation based on either a NAME or a PATH
on getPresentation(desc)
    tell application "Microsoft PowerPoint"
        if (item 1 of desc) is "" then
            return item 1 of (get presentations whose path is (item 2 of desc))
        else
            return item 1 of (get presentations whose name is (item 1 of desc))
        end if
    end tell
end getPresentation

-- Fetch a currently open presentation (just an example)
-- this exists if you open a new presentation in PPT (no saving) and enter as title test
set pres to getPresentation({"test [Autosaved]", null})

memory's setObject:pres forKey:"presentation"

This throws the following error: error "Can’t make «class pptP» 2 of application \"Microsoft PowerPoint\" into the expected type." number -1700 from «class pptP» 2

I'd like to be able to store the object pres for future use, refering to it from the containing Objective-C code (through NSAppleScript, calling methods on pres through wrappers as needed). I can tell the applescript to store the result of some handler at some address and use it later on.

I've tried using a reference to pres to solve the issue, but no luck.

Is there a way to solve this? Perhaps a wrapping class around pres that allows it to be stored inside the NSMutableDictionary? Perhaps I can roll my own Objective-C code that would work on pres?

Any help would be much appreciated!

Max Snijders
  • 374
  • 2
  • 10
  • 1
    You cannot expose AppleScript objects (in terms of Scripting Definition `elements`) to Objective-C unless there is an equivalent like `list` → `NSArray`, `date`→ `NSDate`, `file` → `NSURL` – vadian Jan 08 '19 at 16:11
  • @vadian I'm not interested in accessing the object's properties from the ObjC side, I just need the NSMutableDictionary to keep a reference retained so that it persists and can be retrieved from the AppleScript side later on – Max Snijders Jan 08 '19 at 18:12
  • Then why not an AppleScript record? `set memory to {presentation:pres}`. It's even mutable – vadian Jan 08 '19 at 18:14
  • I'd like to keep many different objects in memory and add more on-the-fly – Max Snijders Jan 08 '19 at 18:15
  • I'd also like to have the storage location be passable from the ObjC side so I can do stuff like "get the current presentation into location x" "use presentation from location x and do y" – Max Snijders Jan 08 '19 at 18:17
  • And If you use an ObjC collection type the value is exposed to ObjC even if you don't access it from ObjC – vadian Jan 08 '19 at 18:18
  • Fair enough. Do you know of a pattern that allows me to have dynamic, indexed storage in AppleScript of AS objects? – Max Snijders Jan 08 '19 at 18:20
  • Again, what's wrong with AppleScript record? OK, the keys are actually not strings but the functionality is quite the same. – vadian Jan 08 '19 at 18:23
  • Its because I'd like to be able to use a string to add new items. I.e. from the ObjC side tell the AS to store a certain value at a location that I generate at that time. – Max Snijders Jan 08 '19 at 18:26

1 Answers1

2

AppleScript’s reference type is not bridged to ObjC so cannot cross the bridge directly. You can wrap it in a script object (as long as that object inherits from NSObject) and pass that over, though in past experience I found creating and using large numbers of bridged script objects also causes ASOC to crash.

Easiest solution is to keep AS references on the AS side, and store them a native data structure such as a key-value list, binary tree, or hash list. (e.g. My old Objects library provides reasonably fast DictionaryCollection (hash list) objects created for exactly this reason.)

foo
  • 254
  • 2
  • 3