Automator Action - read/set Parameters

Hi,

I am new to AppleScriptObjC and have some problems switching over to it.

I wrote some Automator Actions in Applescript and I want to transfer them to 10.6.

But I couldn´t yet find out how to adress the paramters in the predefinded “Parameters”-Object of the action (getting/setting them).
I found a line of code that does this in Cocoa (p.e. for a boolean parameter), but I don´t now how to translate it to ASOC:

BOOL showurl = [[[self parameters] objectForKey:@"checkboxurl"] boolValue];

And how do I set the parameter´s value?

Thx!!!

There are a couple of ways. You can get the parameters as an NSDictionary and call methods on it something like this:

set parametersDictionary to my parameters()
set showurl to parametersDictionary's valueForKey_("checkboxurl") as boolean

But I’d be inclined to coerce the properties dictionary to an AS record and try using it accordingly, something like this:

set parametersRecord to my parameters() as record
set showurl to checkboxurl of parametersRecord

Thank you, that´s great!

It looks so simple, but these things are so hard to find out, if you “only” know AppleScript. With no docs or examles anywhere (TemperatureConverter isn´t an action).

I will provide a sample ASOC Action (Testaction) for beginners like me with code for the handling of gui and workflow input as soon as I know enough.

I´m still stuck at some points, like localized strings, the NSDatePicker’s dateValue() and strange error logs.

Good luck! One of the great things about 10.6 is that Automator actions written in AS have access to AppleScriptObjC, which means much greater capabilities.

Maybe someone wants to check out the testaction I put on sourceforge to help me solve the open problems. I think it is pretty straight.

FYI, there are a couple of smple projects at http://www.macosxautomation.com/automator/examples/ex04/index.html.

long time later…

reading the parameter’s values works fine, but how do I set them?

I bound parameter values to interface elements like steppers and number formatted text fields. These parameter values get updated only when changing the values in the interface, not when changing them programmatically - like changing hours to “1” when minutes are set to “60” by the user.

Thus the displayed values are different from the actual parameters.

I already tried a lot like the following (the key “uiMinutes” is defined in AMDefaultParameters):

set ParametersDictionary to my parameters()
ParametersDictionary's setValue_forKey_(0, "uiMinutes")
log ParametersDictionary's valueForKey_("uiMinutes") -- returns: AMBundleAction

So I don´t even get the variable updated, updating the real vlaues of the paramaters fails as well:


my parameters's setparameters_(ParametersDictionary) -- fails

Off the top of my head, I’d try something like:

set ParametersDictionary to my parameters()
ParametersDictionary's setValue_forKey_(0, "uiMinutes")
set my parameters to ParametersDictionary

Hi Shane,

the last line,

set my parameters to ParametersDictionary

raises the error:

** INTERNAL ERROR: Uncaught Exception **
Exception: [<AMBundleAction 0x1002038e8> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key parameters.

It may be important to note that the code is part of an action handler, not the “on run”-part of the script. (I use a “Reset”-Button´s action handler for these experiments because here I need to set the parameters programmatically as well).

The parameter key “uiMinutes” does exist in Info.plist and I can read it without problems in the “on run”-script. In the action handler however, the value for “uiMinutes” returns “AMActionBundle”.

The handler looks like this and is called by a button:

on resetTimes_(sender)
		TFMinutes's setIntegerValue_(0)   -- resetting the interface elements, 
		TFMinutes's setStringValue_("0")   -- this does not refresh the bound parameters
		STMinutes's setIntegerValue_(0)
		TFHours's setIntegerValue_(0)
		TFHours's setStringValue_("0")
		STHours's setIntegerValue_(0)
		TFDays's setIntegerValue_(0)
		TFDays's setStringValue_("0")
		STDays's setIntegerValue_(0)
		TFMonths's setIntegerValue_(0)
		TFMonths's setStringValue_("0")
		STMonths's setIntegerValue_(0)
		TFYears's setIntegerValue_(0)
		TFYears's setStringValue_("0")
		STYears's setIntegerValue_(0)
		try
			set ParametersDictionary to my parameters()
			log "old uiMinutes = "
			log ParametersDictionary's valueForKey_("uiMinutes")
			ParametersDictionary's setvalue_forKey_(0, "uiMinutes")
			log "setValue_forKey_ executed"
			set my parameters to ParametersDictionary
			log "new uiMinutes = "
			log ParametersDictionary's valueForKey_("uiMinutes")
		on error
			log "error using dictionary"
		end try
	end resetTimes_

According to the sample, it’s:

 my parameters()'s setValue_forKey_(exportFieldNames, "exportFieldNames")

And makes sure you use “setValue”, not “setvalue” as you posted.

Xcode always compiles it to a lowercase “v”, so I tried now:

my parameters()'s |setValue_forKey_|(0, “uiMinutes”)

But when I run the action, the value of the key “uiMinutes” still is not zero, but the arbitrary value I had set beforehand with the stepper.

If it helps, you can find the project files here:
http://sourceforge.net/projects/icaldoit/files/nightly%20builds/move%20events%20by%20offset%200.5a0.zip/download

That’s AppleScript’s doing because you typed it that way first. You need to open the file outside Xcode, change the first such “v” without compiling, save, then try again.

I replaced it in TextWrangler, now it´s spelled correctly.

But this does not solve the problem. It is like if there was a difference in runtime on accessing the parameters, depending on configuring or running an action.

my parameters()'s setValue_forKey_(59, "uiMinutes")

has no result in the handler, but works well in the “on run”-section of the script.

In your script you have:

At this stage, parameters() and ParametersDictionary are two completely separate things; ParametersDictionary is like a snapshot of the way parameters() was. Change the last line to:

			log parameters()'s valueForKey_("uiMinutes")

You´re right. While trying out different approaches, the code got somewhat inconsistent.

However, correcting it does not help. The log still results to “AMBundleAction” as before.

The expected result, in either case, should be a number, not “AMBundleAction” - a class (?).

What do you get logged if you also put that log line before the setValue_forKey_?

log parameters()'s valueForKey_("uiMinutes")
my parameters()'s setValue_forKey_(0, "uiMinutes")
log "new uiMinutes = "
log parameters()'s valueForKey_("uiMinutes")

Debugger Console:

2012-04-30 15:25:36.487 Automator[1416:a0f] AMBundleAction
2012-04-30 15:25:36.487 Automator[1416:a0f] new uiMinutes =
2012-04-30 15:25:36.487 Automator[1416:a0f] AMBundleAction

That suggests the problem happened before you got to trying to set the new values.

So the problem happens before any of my code is being executed. What can I do about it?

It could be an issue with bindings though. I´ll try to describe it:

In main.xib, there´s

File’s Owner, class: AMBundleAction, Outlets view->View, Referencing Bindings parameters-> Content Object Parameters
First Responder—
View—
Parameters, class: NSObjectController, Outlets none, Bindings: Content Object->File’s Owner parameters, Referencing Bindings uiMinutes->Multiple (Value TextField, Value Stepper), Bindings: Content Object-> File’s Owner parameters
Application—
“Move events by offset”, class: move_events_by_offset, Outlets: view->View, BTReset->RoundedTexturedButton, …, Received Actions: resetTimes

Then disconnect them and see if the problem goes away.

Sorry, but it’s ages since I’ve looked at building Automator actions. They’re a pain to test (as you know!), and I just don’t have the time at present.