I am running into issue with using the following runScript withParameters subroutine when using arguments the contain a list.
Error: -[__NSArrayM fileSystemRepresentation]: unrecognized selector sent to instance 0x600006ceced0
Code:
set theResult to (my runScript:"SomeScriptFile" withParameters:{aTextItem, aTextItem, aList, anotherList})
on runScript:theScript withParameters:arguments
tell application "System Events"
set theScpt to POSIX path of (first file of folder scriptLocation whose name begins with theScript)
end tell
set argumentList to {theScpt} & arguments
set executableURL to current application's |NSURL|'s fileURLWithPath:"/usr/bin/osascript"
set {theTask, theError} to current application's NSTask's launchedTaskWithExecutableURL:executableURL arguments:argumentList |error|:(reference) terminationHandler:(missing value)
theTask's waitUntilExit()
set status to theTask's terminationStatus()
if status as integer is 0 then
log "Task succeeded."
else
log "Task failed."
error "There was an error running"
end if
end runScript:withParameters:
If anyone has a recommendation on how to resolve, please let me know! Thanks
The first thing to check in cases like this is the value of any errors that might be returned. Check if theTask
is returned as missing value
, and if so, check the value of theError
.
It seems to be related to passing an argument containing a list of items and lists.
@Shane_Stanley
For example this errors:
set theArgs to {"SomeItem", "AnotherItem", {"A", "B", "C"}, {"1", "2", "3"}}
set theResult to my runScript:"test script.scpt" withParameters:theArgs
I’m assuming it needs to be converted to list of string(s) but do not know how to handle the lists. If it was being passed to a subroutine it would be easy to use:
on runSpecialScript(itemA, itemB, listA, listB)
But it is being passed to another script. I guess what I should be asking is what’s the best method to pass multiple variables containing items and lists to Script B when the script is run from Script A?
Humour me and check the error as I suggested:
set {theTask, theError} to current application's NSTask's launchedTaskWithExecutableURL:executableURL arguments:argumentList |error|:(reference) terminationHandler:(missing value)
if theTask = missing value then
display dialog (theError's localizedDescription()) as text
I used the following code with adding your line:
on runScript:theScript withParameters:argItems
tell application "System Events"
set theScpt to POSIX path of (first file of folder scriptLocation whose name begins with theScript)
end tell
set argumentsSerialized to my serializeValue(argItems)
log argumentsSerialized
set argumentList to {theScpt} & argumentsSerialized
log argumentList
set executableURL to current application's |NSURL|'s fileURLWithPath:"/usr/bin/osascript"
set {theTask, theError} to current application's NSTask's launchedTaskWithExecutableURL:executableURL arguments:argumentList |error|:(reference) terminationHandler:(missing value)
theTask's waitUntilExit()
if theTask = missing value then
display dialog (theError's localizedDescription()) as text
else
log "not missing value"
end if
set status to theTask's terminationStatus()
if status as integer is 0 then
log "Task succeeded."
else
log "Task failed."
error "There was an error running"
end if
end runScript:withParameters:
And the dialog showed no error. It displayed the error task failed catch since Status as integer is not 0.
The variables are as follows:
executableURL = (NSURL) file:///usr/bin/osascript argumentList = /Users/myuser/Desktop/Automation Tools.app/Contents/Resources/Scripts/SomeScript.scpt, {"WTF", "WTF", {"A", "B", "C"}, {"1", "2", "3"}}
The line using them that fails with item 2 & item 3 as lists:
set {theTask, theError} to current application's NSTask's launchedTaskWithExecutableURL:executableURL arguments:argumentList |error|:(reference) terminationHandler:(missing value)
Yes same error. I guess it’s because I’m trying to use an array as string because arguments are expected to be and array of strings?
For easier testing I shortened code and eliminated the subroutine with launchTaskWithExecutableURL. Here is my code I was able to convert argument to string prior to sending and did not fail Now I need to convert the argument back from:
string value = (*{"WTF", "WTF", {"1", "2", "3"}, {"1", "2", "3"}}*)
to
{"WTF", "WTF", {"A", "B", "C"}, {"1", "2", "3"}}
Here is the complete code:
use framework "Foundation"
use scripting additions
set valueToBePassed to {"WTF", "WTF", {"1", "2", "3"}, {"1", "2", "3"}}
set serializedValueToBePassed to my serializeValue(valueToBePassed)
set argList to {"/Users/me/Desktop/somescript.scpt", serializedValueToBePassed}
set executableURL to current application's |NSURL|'s fileURLWithPath:"/usr/bin/osascript"
set {theTask, theError} to current application's NSTask's launchedTaskWithExecutableURL:executableURL arguments:argList |error|:(reference) terminationHandler:(missing value)
theTask's waitUntilExit()
if theTask = missing value then
display dialog (theError's localizedDescription()) as text
else
log serializedValueToBePassed --> (*{"WTF", "WTF", {"1", "2", "3"}, {"1", "2", "3"}}*)
log theTask --> (*<NSConcreteTask: 0x6000042a6b70>*)
end if
on serializeValue(theValue)
-- Returns the text representation of the input value
set tid to AppleScript's text item delimiters
try
|| of {theValue} -- embedding the object in a list allows proper handling of certain object types (e.g., script objects)
on error m
try
set AppleScript's text item delimiters to "{"
set m to m's text items 2 thru -1 as text
set AppleScript's text item delimiters to "}"
set serializedValue to m's text items 1 thru -2 as text
on error
error "The input value could not be serialized."
end try
end try
set AppleScript's text item delimiters to tid
return serializedValue
end serializeValue
Seems like it! Thank you for your help. Im going to explore saving the dictionary vs creating a library and call the subroutine instead of an outside script. I had no idea arguments could not contain lists and had to be strings in this situation. The whole purpose of this exercise was that I created a helper app to trigger running a script from a link on web page, pass an argument through the link to read an API and want to pass the results to a script to keep the helper app minimal. Thanks again!
I agree. It’s been on my list to explore and learn for over a year now. Time constraints force me to use AppleScript/ApplescriptObjC with some Javascript and Shells to automate. I also have better control over the local environment. I have to figure out how to trigger an AppleScript in Node-Red/nodeJS and then I would have the best of both worlds. A web app driving a local app.