@peternlewis, based on the script by @ComplexPoint, and my own testing (both AppleScript and JXA), it does not appear possible to create KM Dictionaries using direct scripting terminology in the KM Engine. @ComplexPoint had to resort to using dynamically created KM Macros, which were then executed using the doScript command.
If I’m missing something, and there is a more direct way in either AppleScript or JXA, please advise.
Here is my test script, based on the JXA functions provide by @ComplexPoint.
This works, but does require use of dynamically created KM Macro.
JXA Test Script to Create a Dictionary
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Creating @KM @Dictionaries from Script @JXA
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DATE: 2018-02-15
REF:
• Creating KM dictionaries from Scripts by @ComplexPoint
• https://forum.keyboardmaestro.com/t/creating-km-dictionaries-from-scripts/8249
*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Function to Create KM Dictionary with Key and Value
// • Apparently this cannot be done with normal AppleScript or JXA
// • Appears to Require Use of Dynamically Created KM Macro
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// kmDictValueSet :: String -> String -> String -> KM ()
const kmDictValueSet = (strDict, strKey, strValue) =>
Application('Keyboard Maestro Engine')
.doScript(plistMay([{
MacroActionType: 'SetDictionaryValue',
Dictionary: strDict,
Key: strKey,
Value: strValue
}])
.just);
// plistMay :: JS Object -> Maybe Plist String
const plistMay = jso => {
var error = $();
const maybeString = $.NSString.alloc.initWithDataEncoding(
$.NSPropertyListSerialization
.dataWithPropertyListFormatOptionsError(
$(jso),
$.NSPropertyListXMLFormat_v1_0,
0,
error
),
$.NSUTF8StringEncoding
);
return Boolean(error.code) ? {
nothing: true,
msg: error.localizedDescription
} : {
nothing: false,
just: ObjC.unwrap(maybeString)
};
};
//~~~~~~~~~~~~~~~~~~~~~~ MAIN SCRIPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var kmDictName = "JXA_Dict1";
var kmKeyName = "JXA_K1";
var kmKeyValue = "Created by JXA";
var oDict = kmDictValueSet(kmDictName, kmKeyName, kmKeyValue)
var appKME = Application("Keyboard Maestro Engine")
var kmDictList = appKME.dictionaries.name();
kmDictList
If I am correct, please consider this as a feature request to provide explicit scripting commands to create KM Dictionaries, and KM Dictionary Keys.
tell application "Keyboard Maestro Engine" to ¬
make new dictionary with properties {name:"TestDict"}
the output returns the new dictionary id, suggesting it has been created. However, retrieving the dictionary fails, and get dictionaries reveals it does not exist.
I wonder if the dictionary does, at one point, get created, but then immediately destroyed for having no keys contained in it. After all, if I take an existing dictionary and set all of its keys’ values to an empty string, this immediately deletes the dictionary.
Yep, I’ve observed the same behavior.
Furthermore, I have been unable to find a way using AppleScript to set the properties for make new dictionary that include a Dictionary Key and value.
I have improved the AppleScript handling so that this will work:
tell application "Keyboard Maestro Engine"
set m to make new dictionary with properties {name:"DictName"}
tell m to make new dictionary key with properties {name:"KeyName", value:"TheValue"}
end tell
I have done this for a future version (after the next version).
I've been playing around with dictionaries and wanted to see if anyone has had any success in created them with JXA. The following works fine for creating a dictionary:
Where I'm running into issues is trying to append a DictionaryKey class into dict.dictionaryKeys. The closest I've gotten without running into the generic Error -10000: AppleEvent handler failed. is the following
Do you need to do it in JXA specifically, or are you happy using regular AppleScript, for which, I believe, scripting the creation of dictionaries and keys works fine.
AppleScript
tell application "Keyboard Maestro Engine"
set D to make new dictionary ¬
with properties {name:"TestDict", id:"TestDict"}
tell D to make new dictionary key with properties ¬
{name:"TestKey", id:"TestDict:TestKey", value:"It worked!"}
get the value of every dictionary key in the dictionary named "TestDict"
end tell
Thanks @CJK. I should have noted that I know it works fine in AppleScript. Mostly just trying to get JSX to work. I know it should work, it's just a matter of getting the syntax right.
The script's all do different things. Peter's script was aimed a creating new dictionaries. The snippets in the Wiki are aimed at retrieving dictionaries or keys and setting values for keys of dictionaries that already exist.
I just tested the three snippets on the Wiki page to which you linked, and I can confirm that they each perform their function correctly.
What did you try that failed to work (and what were you hoping it would do that it didn't) ?
I thought this script would allow me to create a Dictionary, Names and Values in one step. I was wrong.
tell application "Keyboard Maestro Engine"
set value of dictionary key "P" of dictionary "First Names" to "Fred"
end tell