Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2006-125
$eventId
ID of event: wwdc2006
$eventContentId
ID of session without event part: 125
$eventShortId
Shortened ID of event: wwdc06
$year
Year of session: 2006
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC06 • Session 125

Creating Great Automator Actions: Advanced Topics

Application Technologies • 38:16

Move beyond the basics to develop outstanding Automator actions. Gain insight into strategies to create enhanced Objective-C, AppleScript, and shell scripting actions which will enable your users to create more powerful and more generalized workflows. You will also learn how to create new data types and conversion actions, an important aspect of a solid set of actions for any application.

Speaker: Kerry Hazelgren

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Good afternoon. Welcome. This is Creating Great Automator Actions: Advanced Topics. I'm Kerry Hazelgren, and hopefully most of you were able to attend the session earlier this morning, Creating Great Automator Actions: The Basics. That session dealt mostly with what you can do today in Tiger to create great Automator Actions. In this session, though, we will focus mostly on Leopard and a couple of advanced topics for Tiger. So let's start.

We're going to start by giving a brief overview of some of the new features that we have planned for Leopard for Automator. And then we will go into some of those features in depth. And then we'll talk about application integration, which is a new thing that we've added for Leopard where you can actually integrate Automator workflows into your application.

Okay, so what is new for Automator in Letbird? First of all, we have variables. And this is a great new way for actions in a workflow to be able to share data which is independent from the actual data that's running through the workflow. And we'll talk about this in depth and give some demos on it.

Okay, so what is new for Automator in Letbird? First of all, we have variables. And this is a great new way for actions in a workflow to be able to share data which is independent from the actual data that's running through the workflow. And we'll talk about this in depth and give some demos on it.

Okay, so what is new for Automator in Letbird? First of all, we have variables. And this is a great new way for actions in a workflow to be able to share data which is independent from the actual data that's running through the workflow. And we'll talk about this in depth and give some demos on it. Next we have Automatic Serialization. It's kind of a long title and a complex topic, but we will go into that further in depth in a few minutes.

And lastly, performance improvements. Yay! I actually wanted Lightning McQueen on here, but they told me that nothing could possibly be that fast. But I tried to convince them and basically we're left with this. But the point is, Automator has got a lot of performance improvements, both in the UI and workflow execution. We've done a lot to try and streamline and speed everything up.

So we wanted to highlight that. So let's go into some of the new features. We're going to talk about variables first, then automatic serialization, and then we're going to talk about the To finish up, sort of with defining data types and creating conversion actions, two topics which pretty much go hand in hand. So let's start with variables.

Variables, you can think of variables as global variables. They're a way that actions in the workflow can share data. So, for example, if you have an action that creates a new folder and then an action that creates a disk image and one that creates a package, they can all share a variable that would represent the name of the folder, the name of the disk image, the name of the package. And you can, every time you run the workflow, you can just change the value of that variable and it will change the entire behavior of the workflow without actually modifying the actions themselves.

So they're really flexible. We've given you four types for now, and you can set them either in the UI or you can set the values programmatically, and we'll talk about that. One thing you do need to do is to add support for variables to your actions, but it's really easy to do. The first thing you need to do is we've created a palette because we provided a couple new classes. So there's a new Automator palette that's compatible with Interface Builder 3 and it's located in Developer Extras, Palettes, and is called Automator Palette.

Simple enough. So just load that up. And then we've got two controls that support variables. The first is text fields. So you'll want to change any text fields in your action UIs to token fields. And there's a somewhat fuzzy screenshot. We don't have high DPI yet. But there's a screenshot, and that's what a variable looks like in a text field. It's a token, just like you would see in a mail message. Then also pop-up buttons support variables. And if you have an NSPopupButton, you will want to change that to NSPopupButton. and pop-up button. And you can see there's a little variables icon next to the value.

Before I go to the demo, there is one other control, the AM Path pop-up button, which we introduced in Tiger for Automator. If you have one of those, we use them a lot in Apple's actions, they support variables automatically. That's one thing you don't have to mess with. So to demo variables, I'm going to bring up the engineer that was mostly responsible for implementing them, and you may have seen her this morning, and that would be Emily Kim.

Emily? Hi, so if you didn't see the session this morning, I'm Emily, and we're going to talk about a little bit about variables. So what I'm going to show in this demo is how you can change the controls in your action to take advantage of the variable features in Automator, and then we're going to take a quick look at how these variables can be extremely useful in your workflows. So to the demo machine, please.

So here I have a project. This action imports photos into iPhoto. So all I have to do is open up the Nib in Interface Builder. And here I have my text field. And I'm going to show the inspector. And here all I have to do is change its class to AM Token Field, just like that. Save it. And that's actually all I have to do. So now I have already a built version that I'm going to use to show you. And we're going to get some pictures.

And that's actually what I just did was drag some files into Automator. In case you didn't know you could do that, it'll create a get specified finder items for you, and I think that's very exciting. So then we'll make a new folder, get the pictures out of the folder, and then we are going to import these photos into iPhoto.

And to take advantage of variables, let's say I want to have, this is actually a workflow that I use when I'm getting the photos from my camera onto my computer. And so I like to keep them in a separate folder and then I import them into iPhoto without taking advantage of iPhoto's directory structure. So I'm going to have a variable here called album. Its value is nature. And so I'm going to put it in the name of my new folder. And I also want it in my album name.

So, nice auto complete. And then I can also add the current date to my album, which is what I often do in iPhoto. And this is also extremely useful because currently there are a lot of Automator actions which just say append current date to this file name. And now you can just use variables and put that wherever you want.

So you can see we have that. And then as Kerry mentioned, we also have support for Path Popup buttons. So I can drag a path type variable into one of those. So now what I have here is a workflow which takes some photos and creates a new folder with a name that I've specified in a variable in a destination that I've specified also as a variable. And then it imports them into iPhoto using the album name, which is the same as the folder name, as well as the current date. So what happens when I run this? We're going to hit run.

And here you can see it's imported the photos into an album that has a variable name and the current date. So, that's kind of exciting, but what if I just hard-coded nature and the date in and that would have been fine? Well now what I can do is I can actually change the value of this variable to something like pretty pictures, and then maybe change the photos since I already have these to these photos.

And maybe I also want to change the format of my date. I want to change it to this one now. So all I have to do is change those and run the workflow again and you can see now I have another album called Pretty Pictures and a current date in a new format.

You can see how this could become extremely useful, especially with path pop-up, with A and path pop-up buttons, if you keep your variables. If you have a lot of actions that are dealing with data going all into the same place, you can set the path once in the beginning of your workflow and it will use that same path for the rest of the workflow.

Kerry Hazelgren Additionally, we also have a new results feature. If you just turn the action over, you can see results on the other side in a better form than what we currently had, which was this. Now we have also, you can see them as a list or you can see them as pictures. That's that. Back to slides, please.

Thanks Emily. She promised she would be nicer to me than she was to Todd this morning. So far, so good. Okay, so the next topic is Automatic Serialization. And basically this is a way whereby Automator can take the data that is flowing through a workflow and serialize it so that actions can just receive one piece of input at a time and loop over them.

Now I said loop. It is essentially looping, but it is not the kind of looping you would expect because it's not user configurable. It's based on certain properties of the action. So we didn't really want to call it looping. We call it automatic serialization. And I've got a nice diagram to demonstrate or to explain it.

So in Tiger, in a typical workflow, you would start with a group of data such as this. And the first action would receive that data and it would iterate over the data. Essentially it would loop inside the action. From that action to the next action to the next. And then you would have your output again essentially a list. Automator and Tiger dealt mostly with lists of data. So, this works great for most workflows and most actions, but for a certain class of actions, it can be really problematic.

If the task is to open open a Photoshop file, for example, and you get past a list of 50 of them, you don't really want to be opening 50 Photoshop documents. At the same time, you would quickly eat up all your system resources. In fact, one of our developers developed a suite of Photoshop document or Photoshop automator actions, and he had to come up with a clever workaround for this sort of a workflow. The good news is, though, we made that a lot easier.

And the only thing you have to do to take advantage of it is change the input type of your action from list to single. And I'll show you how to do that. You may have seen a little bit of that this morning. So if you do that, let's look at how a workflow in Leopard would behave.

So we have five actions here. And the first one and the last one take a single list input. The center three, however, take single input. So once we run this workflow, we'll get a list of data, and the first action will iterate over that data until it is finished processing it.

Well then at this point, Automator is going to say the next three actions require single input and the added criteria is that they are part of the same application. So they're all Photoshop actions, they're all iTunes actions, they're all your application's actions. So at that point, Automator will create a loop and it will just send the first item of data through that loop.

"And then it will go to the second, and the third, and the fourth, and it will temporarily hold the results of that loop." Until it is completed, iterating all of the data. So once it has done that, then it'll send that through to the next action, which will receive a list as it requires.

"And it will process it and all is good. So it works, most actions will work just the same if it's good for them. But actions which need this behavior, require it really, can take advantage of it. So it's not for every action, but if it is a data intensive action, this is really handy. So all you need to do to set your action to single input is open up the project, select your target.

And in the inspector, under the container type, input type, select single. This was mostly unused in Tiger, so most of your actions most likely are set to list, but you can take advantage of that and set it to single.

[Transcript missing]

So here I have a workflow. And it's going to start with getting some files.

Copy files to the desktop with this action. I have slightly modified versions of Flip Images, Crop Images, and Scale Images that all take single input. All I did was change the input type of those actions. It will end up with Open Images and Preview, which is another list type input action. As you can see, when this runs, it's going to copy them all to the desktop, but then it's going to loop over each item of data, just processing them one at a time until it completes.

The last action got all of the data at once because it opened them all as a set.

[Transcript missing]

Again, it's not for most actions, but if this sort of behavior is important to your action, please go ahead and take a look at it and see if it's right for you. Now the next feature.

is defining custom data types. The typical scenario of an Automator Action Developer, well, an Apple Script Automator Action Developer, is you have a scriptable application, and it defines in its scripting terminology certain objects, and you want to create an Automator Action that will deal with those objects. We do that with mail actions. Like mail messages is a type that we define.

Mailboxes, et cetera, iTunes songs, those are all data types that we have defined. So if you're creating an action that has an input type or an output type of one of your custom objects, then you'll want to define a data type so that Automator knows how to work with that object.

Data types in Automator are UTIs. And UTIs are simple strings, reverse domain name formatted strings, that can represent any object. And Automator defines a number of them, which you can, let's see, in the Automator Programming Guide, there's a whole list of types that Automator defines. We have types for strings and paths and all sorts of things.

I can't name them all right here, but we have a lot of them. And so you can use these existing types, but a lot of times you will need to define your own. So how do you do that? What you want to do is come up with your string, your UTI, and then you'll want to create a definition bundle.

"Or a definition file, as we call it. And what you want to do is open up Xcode and go to the new project template. You will see a definition bundle type there. Select that, open it up, and what you will see is a property list where you can add or define your types there along with the human readable name. That is important because Automator in various locations displays the name of your type. Automator behind the scenes acts on the UTI type but displays the human readable name to the user. Amen.

So once you've got that, just build it and install it. And it can go in any of the appropriate library automator type locations. Or it can even go in the bundle of your application. If you put a library slash automator folder in the bundle of your app, you can put a definition file in there. You can even put actions in there. Don't know if you knew, but you can put actions in there. And once your app is installed, Automator will automatically see those actions. And they'll be loaded when Automator starts up.

But you're not really done there, because defining a custom data type isn't the whole story to allowing Automator to play with your object. Because it needs to really be able to convert from your custom object type to other types that it already knows about. And that's where conversion actions come in.

Emily talked a little bit about conversion actions this morning. But basically what they do is they convert or filter "Your data that's flowing through a workflow. An example of filtering it would be an action that outputs files and folders and the next action requires image files. So the conversion action would just filter out anything that isn't an image file.

The cases of actually converting data or things like in this example where we have an action that outputs an iTunes song, well the next one requires files and folders. So what the conversion action does, which gets executed automatically, it just takes a property. I think the path to the song is a property of an iTunes song. So it extracts that property and passes that along. So conversion actions are really important for your actions to be able to seamlessly coexist in the whole Automator world.

The way that you create an Automator Action, they're really just special types of Automator Actions. You would follow all of the steps to create a regular Automator Action, but It has no UI, so you don't have to worry about that. You can, in fact, delete the main nib. And then you want to take one more step and change the product extension from Action to C Action.

And that's all there is to it. That's actually the really important part. You can leave the main nib if you want. It won't get shown. But the one thing that Automator looks at is the product extension. And if it's a C action, it considers that a conversion action.

And I'm not going to go into how to do it. We demoed that last year. And there's documentation on it in the Automator Programming Guide. But just to give you a little understanding about why conversion actions are important and how they exist with your custom objects and your custom data types. And now we get to go on to the really exciting part. This is the part that I worked on for Leopard.

New for Leopard, you are able to load an Automator workflow in your application, execute it, and receive the results back in your application as well. We have new APIs and new objects that allow you to do this.

[Transcript missing]

So here's the new objects in the Automator framework. The controller object obviously acts as the link between AM workflow and AM workflow view.

Now these are the same objects the Automator itself uses. The view especially is the same view that you see in Automator and we'll show it later in a demo. You may have seen, if you recall in the Developer Tools State of the Union, Todd demonstrated an Automator workflow in Xcode. So, AM Workflow. This is the model object for a workflow, and you load it simply by passing it a URL to an Automator workflow. Then you can access the properties, or the actions rather, and the input, and the variables as well.

The NaM Workflow Controller is the controller object that is mostly responsible for running a workflow. It also has a set of delegate methods that you can optionally implement to get progress on the running of the workflow. You can use it to run a workflow, such as when the workflow starts or stops, when an action starts running or stops running, or when an error occurs.

And then there's AM Workflow View, which is not yet present, but it will be for Leopard, and will allow you to view the actions in a workflow, edit them, add, remove, delete, all of that. So that behavior, like creating new workflows, is not yet present in the seed, but it will be.

So what you can do currently is you can still load a workflow, change the value of a variable, and save your changes. So here's a little bit of code on how you would load a workflow. You would start by a URL or a path to an Automator document, and you would pass that to AM workflow, init with contents of URL, and then there's also an error parameter.

And then if the result is nil, then an error occurred and you can inspect the error. Then how would you get the variables? Pretty simple-- value for variable with name. And that will return you the value of a variable. You do have to know the names of the variables beforehand. There isn't an accessor method to get all of the variables, because that doesn't really make sense in an Automator workflow, because you don't know for a given variable name what the actual function of it is.

So we envision this typically as a developer would create a workflow to perform some specific task, and then you would save that and bundle it possibly in the bundle of your app. And then you can load it at will, or when it makes sense to you, and set the values of the variables before you execute the workflow. So that's getting it and then setting the value of a variable you would call set value for variable with name.

Okay, so when it comes time to run a workflow, there are actually two different ways to do it. And one is really, really easy, and the other one is just really easy. "We have a class method, so it's a single line in AM workflow. And then we have, and I'll show you that, and then we have AM workflow controller, which, um, It's a little more work, but you get more control.

And workflows, actually, when you run them, they will run in a separate process. They will not run in your application's memory space. So the point of that is if the workflow or an action in the workflow crashes while it's running, it won't bring down your application. And you're also protected from errors and memory leaks and all sorts of that bad stuff that we don't like to talk about.

Okay, so here's how you run a workflow from the class method. Again, start with a URL to an Automator workflow and then hand it off to AMWorkflow, run workflow at URL with input, and the input is optional. and then there's an error parameter as well. So if an error happens, well if it runs successfully and completes, you'll get, because it runs synchronously, you'll get the results. If the results are nil, then an error occurred.

You shouldn't try and inspect the error if the results aren't nil because we won't have set the error parameter to anything. We're not going to set it to nil, we're just not going to even touch it. So just ignore it if there was no error or if the results were not nil.

But if the results were nil, then the error will be an NSError object that you can inspect to find out what went wrong. I show the error code. We've published also in the Automator Framework a list of the error codes that we return, so you should be able to get a nice description of, or at least understand what happened.

All right, so let's demo. We're going to demo AM Workflow, the class method. And I should probably show it this way if you went to the earlier session, because that'll make more sense to you. And we're going to have Emily demonstrate it for you. Kerry may have written this feature, but I was the one who wrote the cool action we're about to demo, so... Switch to the demo machine, please.

Here I have a copy of TextEdit that I already built, and so I'm going to open up this. I learned from the earlier session. I apologize if anyone couldn't see from the back from the earlier session, so I've learned now. And we're going to convert this to, say, NubText.

That's great. And you can see that we can, straight from TextEdit, convert, basically run Automator workflows on the input. Oh wow, this is completely legible. So to see how we did that, we can open up the TextEdit project and here just in the controller in TextEdit we have a setNudeText. And so you can see that we take the text that was in the document and we find the workflow and then as Kerry pointed out in his slide, we simply run workflow at URL with the input that was in the text document already.

Then we get the result and we basically put it back into the text document. And that's that easy. As he said, it was really, really easy. So that's TextEdit and I'll hand it back to Kerry so he can show you just the really easy way. Back to slides.

Thanks, Emily. Emily came from MIT, so people like that, I mean, they can read stuff like this. It's illegible to me. Okay, so running a workflow with AM Workflow Controller. It's a little more work in that you need to actually load an AM Workflow object and then load an AM Workflow Controller object, but it's still just a few lines of code.

And the delegate is optional, but You will need to implement certain delegate methods if you need to know when the workflow finished, for example, so you can get the output of the workflow, because it runs asynchronously. So this is a bit of code on how that works. We have starting with a URL to a workflow object, then we're going to use that to load an AM workflow.

Then once we have that, we'll allocate an AMWorkflowController object, which is a simple init method. Then we'll use that controller object and we'll set the workflow. We'll set the delegate, in this case to be self. "And then we'll tell it to run. And it'll go off and it'll run.

Runs in a separate process. And if we've got our delegate methods implemented, we'll know when it finished. And we can go and get the actions, we can get the output from each action. And most likely you're interested in the output of the last action, which is the output of the entire workflow."

[Transcript missing]

Okay, now I'm going to demo.

I'm going to show you essentially the same thing that you saw in the developer tools state of the union where we've got it running in Xcode, but then I'm going to show you a little bit of the code and how we did that. So if I have, for example, I have got an action project here.

Demo machine? There we go. Okay, I have an action project here and I can just go to the Xcode application menu and here I've got some workflows that I've built into Xcode. The first one is to create a disk image and it'll take the product or the action that this project builds and it will package it up.

and then take the package and put it into a disk image that we're ready to send off to our beta testers or whoever. Now the nice thing about this, and it shows the really really, really useful integration of AM workflow and variables is that Xcode actually, before it loaded and showed you this, it set the values of the variables in this workflow.

So like right here, the product name has already been sent, set to the product name of this particular project, and the product version has been read and set for this project. So each, no matter what project you open, those variables will be set and will be relevant to the project that you're in. And so if we run this, we We should see that it's going to create a package there on the desktop.

[Transcript missing]

So that's AM Workflow Controller, and that's new and supposedly totally functional in Leopard. So that's all we have for today, and we've learned a lot of important things about Automator in Leopard. Variables, an important new feature, and automatic serialization for those of you who have data-intensive actions, and also application integration and how to create and define custom data types and conversion actions. So for more information, go to http://www.amworkflow.com/application- integration/.

We have an Automator Action Lab directly after this session, well at 3:30. And so come to us in the lab and we'll try and answer any questions you might have regarding Leopard or Tiger or Automator Actions, Conversion Actions, everything. And then there's an AppleScript Studio session and lab tomorrow. Sal Segoian, where's Sal? Sal's there. Sal, who you all know, is here. And Todd Fernandez is the Automation Tools Manager. He knows how to create great Automator Actions. And then we also have an Automator Developer's Mailing List.