Transcript
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Silence ]
>> Hello, welcome to the World
Wide Developer Conference,
this is the second automation
session today, how many went
to first session
this morning...okay.
So our little presentation
about Libraries kind of got
to you a little bit huh,
you're interested in this.
This session we go in depth in
discussing AppleScript Libraries
and we'll examine not only
simple but complex ones
and we'll walk you
through the process
of how you create
those including
for the first time ever
anywhere an example of how
to create a scripting
dictionary.
I think once you
see how it's done,
it's not so frightening
it's pretty easy
to do it's just an XML file.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So today we're going
to be talking
about AppleScript Libraries
and what they can do for you.
Let's try click, welcome, today
it's AppleScript Libraries,
we covered that and we're
going to be learning
about what they are,
how you incorporate them
into your environment, how
you call them, how use them,
how you create them and
how you can deploy them.
So begin with, why
Libraries...those who were
at the first session understand
that I'm one of those kind
of people that is a code
maven, I have sampled routines
that do just about
everything and I have them all
over the place on my drives
and I'm very thankful now
that we have iCloud
support so I can keep them
in one central location
but I like to use routines
and handlers in my scripts quite
a bit instead of writing code
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
over and over, I like
just getting the routines
and handlers and pasting
them into my scripts.
So if you're like me and you
use the same routine over
and over you're going
to like Libraries,
they're going to
be useful for you.
Again if you are a person
that uses third party scripting
additions to find that command
that was missing in
AppleScript you're going
to like Libraries as well.
If you just want to be someone
that can simplify your scripts
if you want to take all
this complexity and routines
and handlers out of your scripts
and just have an easier way
to manage them and to be able
to call them globally throughout
your scripts you're going
to like Libraries.
It all started because you
know once I learned how
to create a subroutine or
handler I started using them
and I would put them in my
scripts and it worked very well
and then I would create
another one and then I would put
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in in some of my scripts and
not in some of the other ones
and I would update one but
I didn't update the other
and then I added more routines
and then the next
thing you know it gets
to be this real big jumble
that you try to manage.
Well we're solving that
issue and those problems now
in Mavericks with
the introduction
of AppleScript Libraries.
They are a new plug in
architecture for AppleScript
that allows you to create
powerful collections of handlers
and tools yourself and deploy
them across your machinery.
In addition, they differ from
the standard scripting addition
that we're used to using all
the time in a couple ways.
First of all they can be written
in AppleScript, you don't have
to know C or C ++ in order to
create an AppleScript Library.
Because Libraries are
loaded by the script,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
the script is controlling
how they use
and that will help you
avoid terminology conflicts
or resource problems, all
of that kind of goes away
because the script is
loading the Library
and the Libraries
live within the space
of the application that's
executing the script.
Now AppleScript Libraries have
some extra abilities to help you
out and the first one
that's really important is
that they can take advantage
of AppleScript objective C.
AppleScript objective C exposes
the Cocoa classes to AppleScript
so things like NSString
become available to you
and all the methods from
that and the instants methods
from that now become
available for you to use
in your AppleScripts scripts
and your AppleScript Libraries.
In addition you can also have
your libraries publish their own
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
terminology which means
instead of you having
to remember a specific handler
name and a specific order
of indicators or
data pass throughs
or whatever you can actually
use English like terms
that you create that work for
you and have those be the way
that you call the
AppleScript Library
so the handlers within
the Library.
So it's very powerful
and in support
of that we've created a
couple new constructs,
the first is a Script Library
reference, a way to easily refer
to a Script Library that you
have installed on your computer.
You'll see how that differs
from the old load Script
that we all used to use
as a substitute for this.
Then finally we've
created a new construct
that is called the use
clause and it's a way
to import terminology and
to bring in dictionaries
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and libraries into your script
and have them be available
globally throughout.
So let's take a look at this,
now in the old days before
this many of us have tried
to use the old script storing
techniques that we had available
through the scripting
addition of load script.
Now if you go to your library
pallet in the AppleScript editor
and you select standard
editions and you open
up the dictionary window for the
standard editions you have nine
suites in the dictionary and
one of those suites deals
with scripting commands and one
of those commands is load script
and here is the definition
for that, let's zoom that in.
Now this command was designed
for you to be able to point
at a specific script file,
load its contents into memory
and then talk to that
script file in memory
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and have it do things for you.
But there are a couple
issues with using this
and here's an example script
that uses the load
script scripting edition.
You can see that the first
thing is you have to know
where the script that you are
using as a library exists,
where is it, you have to
have its exact location
and then once you've identified
where it is then you perform
this load script and store it
into a variable that represents
the contents of that script.
Then elsewhere in your
script you talk to that
and you call its handlers or
whatever handlers are available
within it and have it work but
this is a problem because first
of all it requires that you know
exactly where it is and if it's
on a different machine then
you have to develop way
to locate folders locally,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
regardless of how drives
are named and you have
to have error handlers to
make sure that they're there
and those kind of things
and then it requires explicit
loading, explicit loading,
explicit loading of the targeted
script file, you have to do that
and it also requires that
you address the handlers
from within the loaded
script file directly and pass
through information to them.
This means that there's
no custom terminology,
you have to remember
handler names,
you have to remember the order
of the various components
of the handler and there's
no access to the power
of AppleScript objective C and
the wonderful Cocoa Libraries
that are available
too on the computer.
So there are some issues
with using the load
script scripting edition
and we've addressed
a lot of those
with our AppleScript Libraries
so let's take a look at it.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We're going to start
very simply;
I always like starting
exploring a new concept
in the most fundamental ways.
So we're going to look at
simple AppleScript Libraries,
you might never write
something this simple yourself
but by examining
this we're going
to learn the principles behind
this whole architecture,
is that okay, we'll
start simple...good.
Specifically we're going
to look at a problem
that exists all the time
of solving the missing command
problem, I want to be able
to do something but there's no
AppleScript command for that.
So by examining this little
issue we're going to learn how
to create and use
AppleScript Libraries.
Now for our example of a missing
command here is the new notes
application in Mavericks,
I'm going to select some text
in there and then right click
the selection so it brings
up the contextual menu.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now some of you might know
that for a couple system
releases now we implemented some
new text handling options
within the standard text
contextual menu and one
of them is transformations
where you have the option
to change the case of selected
text to upper case, lower case,
capitalize or that's
called word case sometimes
and you might find it
called that as well.
But this is a command that's
available on the contextual menu
but it's not available from
within AppleScript itself.
So what I want to do is
use this as an example
when we're creating our
simple library to begin with
and we're going to look
at being able to convert
to upper case transformation, so
we'll have something like how,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
now brown cow in lower case
transforms to how now brown cow
in upper case, we're going to
have a lower case transformation
and instead of capitalization
I'm just going
to call it a word
case transformation
where the first letter of
each word is capitalized
and this is what we're going
to use as our sample command.
We're going to look
at this in two types
of simple script libraries,
one where the library is written
entirely in native AppleScript
and two, where the library
is written using AppleScript
objective C.
So just to review
here we're going
to take this missing command of
transformed text and we're going
to use that and create
two simple libraries
to address the fact that's
it's not native in AppleScript.
We're going to create
one in AppleScript,
one in AppleScript
objective C, let's begin.
An AppleScript script
library, so it beings
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
with having a handler some
kind of AppleScript handler
and here I have one,
you'll notice that the name
of the handler is
change case of text,
we'll use this handler
throughout here
and it has two parameters,
one is the source text
or the what you want
to transform,
the text that you
want to transform
and the second is a case
indicator and this case
of this handler it's going
to a numeric value zero
or 1 that indicates whether
you want upper or lower case.
It's a simple AppleScript
based upon your case indicator,
it creates two comparison
lists and then iterate
through all the characters
in the past text
and matches whether
it's an iteration list
and then finally returns
the resulting string back
to the script itself.
Something simple right, now
we're going to take this
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and make this and make
this into a library
and it's simplest
doing the following.
We're just going to take a blank
script in the AppleScript editor
and we're going to paste
the handler into this,
we're going to compile it
and then just click save
and we're going to save
it as a script file
and you'll notice we named it
AppleScript text transform is
the name of this little library.
Now libraries can
contain multiple handlers
but for our example
they're just going
to contain one handler, okay.
And we simply name the
library and then save it.
Next we install the
script library,
and the way that you
install it is you go
to your home library
folder and within
that library folder you create
a new folder called Script
Libraries and then you take your
newly saved AppleScript file
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and you drag that into the
Script Libraries folders
and it becomes part of
the AppleScript system
on your computer, that's it,
it's now installed for you.
So how do you use the
AppleScript script library?
Now that we've created this
simple library with one handler
for transforming the case of
text here's how you use it.
We have a new construct in
AppleScript and it's a way
to identify easily
AppleScript Libraries.
So you no longer need to
point to a specific file
through a file reference
like you did with LoadScript
and you no longer need to
explicitly load the file
and all you need to do now is
you go into a blank script,
you type the word script
followed by the name
of your library and you notice
I left the name extension off,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
you don't need to have
the name extension there.
So script, AppleScript
transform and then
when I compile this you'll
notice that it formats
and this is now a
AppleScript Library reference,
it's a way to point
to that library,
it was automatically located on
your system and it's prepared
for use, it's ready to
go all you have to do
to address it is you can
place the verb tell before it
or in this case you could
enclose it within a tell block
and then refer to
one of the handlers
within that particular library.
So here I have the name of our
handler is change case of text,
I'm passing into the
handler how now brown cow
and I have a case indicator of
one meaning I want upper case.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So I run my script, it
automatically gets processed
by your AppleScript library
and the results are
returned back to the script.
So that's the basic process
of creating a very simple
basic AppleScript Library.
So here's the routine
that we used,
it's a little subroutine now it
does convert case of some text
from upper to lower
and lower to upper
but it doesn't handle special
characters and it doesn't work
with multiple languages.
In order to have an
AppleScript handler to do all
that it might be as
long as I am tall
or a couple times past that, it
would be very complex to do all
that in native AppleScript.
So in this case we need
to turn to something
with a little bit more
power and we're going
to create our second library
example using the power
of AppleScript objective C.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So this will be a
simple library written
in AppleScript objective C,
everybody with me so far?
Not so hard right, okay good.
Okay here's the same handler,
this time it's change case
of text and it gets two things
passed to it, numeric indicator,
I mean the source text that
we're going to transform
and a numeric indicator
indicating text.
But this time the body
of the handler is written
in AppleScript objective
C and the first thing
that the handler does
is convert the past
into a Cocoa string using NS
string method called string
with string, then based upon the
numeric indicator that's passed
through the numeric case
indicator it executes a method
on that instance, either upper
case string, lower case string
or capitalized string.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Once that transforms
been applied and copied
into the variable next
to it adjusted string the
handler returns the adjusted
string back to the script
as text by just saying
as text in your coercion.
So this is the handler
that we're going to use
in our second example library.
We take a blank script
and we paste our handler,
the AppleScript objective C
handler into our script, we save
and in the sheet to save a
little bit of time I'm going
to save it into the
script libraries folder
that I already created instead
of dragging it in the finder.
You can if you...you
can drag if you want to
but for our purposes here
I'm just going to save it
into the newly created
script libraries folder.
Next I'm going to give
it a different name,
I'm going to call this one ASOC
text transform and ASOC stands
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
for AppleScript objective C.
Finally at the bottom
under format instead
of the standard script file
format we're going to choose
to save this as a script bundle
and you'll see why
in just a moment.
So we save our script and then
you'll notice once you've saved
it in a bundle format at the top
menu bar there's a new button
that becomes available and
what that button does is
when you toggle it, it
will show you the contents
of the script bundle so if I
click that a drawer is exposed
and this drawer contains a lot
of valuable information
about this bundle.
First of all it contains the
name of the script library,
it contains its bundle
identifier
where you can put
your developer domain
and name it whatever you like,
it contains a short version
number, a bundle version number,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
a copyright string, the
terminology file name
and a check box indicating
whether this library uses
AppleScript objective C, a
scroll area down at the bottom
that will display the contents
of your resource folder
and a little magic pop up menu
that does particular actions
with things that you've
selected in the resource folder.
So in this particular instance
there's only four things
that we're interested in.
They are...we're going to
start by adding the name
of our library, ASOC text
transform, in the name field,
we're going to give it our
developer domain identifier
so here my company is nighthawk
productions dot asoc dot text
dot transform and then we're
going to give a copyright string
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and most importantly we're
going to check the check box
that says this library uses
AppleScript objective C.
Those are the four
things we want to do
since we're creating a library
that uses AppleScript
objective C.
Once we've done that then
I can close the drawer,
save the script file, now
I've already installed this,
remember I've saved it into
the script libraries folder,
if you didn't you can drag it
in yourself before
doing the next step.
Now that I've had this library
and it's installed how do
you use it, well the same way
that you used the
earlier library,
the first thing you do is
you type the word script,
followed by the name
of the library,
in this case it's ASOC text
transform, you compile it
and you get your
AppleScript library reference,
identifier so this indicates
to me because it's complied
that the script has located the
library, prepared it for use,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
it's ready to go, I can
encase it within a tell block
like I did before, I can
refer to the handler within,
I can pass text into the handler
and my first indicator is
the...case indicator is the
number zero.
So I run it and the result
will be all upper case how now
brown cow.
Let's iterate that case
indicator to the number one,
run it again wa-la [phonetic]
I have all lower case,
let's iterate it again
to the number two
and I will get word case
where the first character
of every word is capitalized.
So this handler is much better
than the earlier handler
that was just written
in AppleScript,
it really has a lot more power
and ability because it taps
into the power of the
Cocoa class NSString
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to do all the heavy lifting.
Now this works by converting
to all the case conversions
we need,
it works with special
characters and it works
with multiple languages.
So this is a very useful one and
to demo this I'm going to bring
up my friend Chris Page from
the AppleScript team, thank you.
[ Applause ]
>> Now this is a script
that Sal showed you earlier
and it has a function that
changes the case of some text
and just a trivial example of
using that and I'm going to run
that script and we can
see the result down here.
We converted this
string to upper case.
So just very quickly I'm going
to give you the quick run
through, this is what happens
when you already
know how to do this.
I'm going to take this
function, I'm going to copy it
into a new script and
I'm going to save it
in the script libraries
folder and the slowest part
of this is giving it a name,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I'm going to call it AppleScript
change case and we're done,
we've now created a library.
Now I'm going to run through
that a little bit slower
for people who are
trying to follow along,
I'm going to copy this
text, create a new script,
paste it in and save it.
Now this is...if this is
the first time doing this
and you don't have the script
libraries folder here's a little
trick you can press Command
Shift G to bring up this sheet
that lets you navigate
to the libraries folder
in your home directory because
the library folder is normally
hidden from users but as a
developer you need to know this
to be able to get
to that folder.
You can also get
there in finder.
Then you would use the New
Folder button to create
that folder and then you
could save the script
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in there and that's it.
I'm going to close
this and now I'm going
to take the client code that
uses this library I'm going
to copy it out of there
and create a new script,
I'm going to close this
one so it's out of our way
and paste the code in.
Now I'm going to show you
how to use the library
if you were following
along earlier,
this might look very familiar,
I'm going to say tell script
AppleScript, change case
and I'm going to compile it
and you can see that it works.
I manage not to misspell
the library name.
If I had just to show you,
if I put an x into the name
which means it's not
going to be found,
when we try to compile it
we get an error that says
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that it couldn't find that
script so you'll know early
on during script development
whether you've referred
to a library correctly and when
I run it we get the same result,
how now brown cow
is in upper case.
That is the simplest case of
using the script library just
to reuse a function
you've been using
in your scripts up till now.
Now we want to take advantage
of AppleScript objective C
to do more than we can
do with AppleScript,
if I take this string
and introduce some accented
characters and run you can see
down here in the results
that the accented o's did not
get converted to upper case.
That's because AppleScript
doesn't have native support
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
for doing case changes and
it doesn't...you would have
to write a very extensive script
to handle all the characters
in Unicode but the foundation
framework that's part
of Cocoa has in a string
class that has a rich variety
of text manipulation functions,
several interesting
ones for changing case.
So we're going to
take advantage of that
in an AppleScript objective
C version of the library
that we already created.
I'm going to create a
new script and save it
in script libraries folder
again, this time I'm going
to name it ASOC change case.
ASOC is a short hand
we sometimes use
for AppleScript objective C
and as Sal mentioned I'll need
to save it as a script bundle
but that's a pretty
easy thing to do.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I'm going to open
the bundle drawer
and update...well the
simplest thing that I have
to do here is enable
AppleScript objective C library,
that makes ASOC available
when this code is running
and while I'm here I'm going
to fill out these other fields.
These fields set values inside
of the info P list file inside
the bundle, there's a lot
of documentation
about how do that
and how the various fields work
if you're unfamiliar with them
and I'm going to fill in a
couple pieces of information,
I've got my...the name, ASOC
change case and I'm going
to put my bundle
identifier in here
which I mistyped...let
me try it again.
Okay the version number default
is 1.0, we highly recommend
that you take advantage
of version numbers
because when you start
distributing and reusing
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and updating libraries you
can use it to distinguish
which version you're
talking about.
I'm going to show you
later there's a way for you
to have your script check
the version to make sure
that it's new enough
for your client script
and I'll put a copyright
notice in here.
But again all we really need
to do was click this check box,
let me put that script aside
for a moment and now I'm going
to put in the AppleScript
version of our library code.
This is essentially the same
function, we haven't changed
that we're just changing
the implementation,
like Sal mentioned earlier
we construct an NSString
from our AppleScript string,
we call the appropriate method
of NSString to do the
capitalization we want
and then we return it
and convert it back
to an AppleScript string.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
All right so that's it we've
created an AppleScript objective
C version of the library
and now let's use it.
I'm going to go back to my
client script and I'm just going
to change the name to match
our new library and I'm going
to run it and this time you
can see in the result pane
that all the accented o's have
been converted to upper case.
Furthermore we now
have a third options
because the NSString
class has a method
for doing capitalization,
it capitalizes every word
in your string, we can put
a different value in here
and run it and so now we've
extended...now we get the word
capitalized version
of the string.
So you can see that using
AppleScript objective C we can
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
go beyond what we
can do in AppleScript
and we can replace large
chunks of AppleScript
that might have had to do
a lot of their own work
with existing framework
functions that are available
on the system to every
other application.
Now you can use them
in libraries
which means you can use them in
your scripts and script applets.
Just briefly I want to
mention that when we look
up libraries we search
in a number of locations,
Sal will mention those later
and we start by looking
in the current applications
bundle which means
that you can conveniently
distribute an applet
that contains libraries that
you want to bundle with it
and the user can just make
that...put that application
on the machine and
run it without having
to install libraries
anywhere before use.
[ Applause ]
Okay thank you.
>> So you can see that
it's not just magic
on a slide you can actually
do this stuff live, right,
and so we were looking at the
example that Chris had there
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and if we look at the syntax
that was involved here,
we have tell the script library
identifier to call this method,
now the short coming in this
whole process or the got cha
in all this process is that
if you have a lot of libraries
or you have complex libraries,
you have to remember the names
of all these different
handlers and you have
to remember what parameters
are passed through.
It would be so much nicer
if I could just...instead
of saying change case
of text like that,
if I could just use some
words I could remember
like transform text and
then give it the text
as a direct parameter to
and then use some word
like upper case instead
of a number or lower case
or word case, I really
want to be able to say this
because I can remember this,
remembering the names of 150
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
or 200 different handlers that's
really a pain, I want to be able
to use this kind of terminology.
So this is what we want to do
as we examine the next thing
of creating libraries
with terminology.
Step one is you start
with the dictionary.
So here is an example
dictionary of a script library,
it's not a really complex one
but it's quite functional,
it has one suite in it,
it's called AppleScript text
utilities, there's two commands
in the suite, one is for
transforming text, the other is
for replacing strings in text.
You can see the definition for
the suite and the definition
for each one of the
particular commands.
This is actually a file;
scripting dictionaries
are actually files
that get displayed within the
AppleScript editor application.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
These scripting dictionary files
are called sdefs which stands
for scripting dictionary
and they are placed inside
of the bundle of your
AppleScript library
so for the first time ever
today we're going to look at how
to create an sdef or a
scripting definition file
or just call the
scripting dictionary.
Now these are XML
based documents,
they have a name
extension of .sdef
and they define the
various scripting elements
that are part of your library.
For example a suite or a command
that might have parameters
and it might also
use enumerations
in the command as well.
In addition you can
include documentation
in your scripting dictionary
so that your customer
or you can actually
see an example script
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that uses the terminology.
So let's look at
how this is done.
This is a scripting dictionary
file, this is an sdef.
It's an empty sdef but it
is a fully formed empty sdef
and you can edit this
with you know any
of the great applications
we have out there
that can edit XML documents.
We're going to use this when
we define our terminology
for an AppleScript dictionary.
The first line is
an XML declaration,
it's a standard declaration
used by every XML file.
Next becomes a reference
to the DTD
or document type declaration.
This is just boiler plate
stuff, it points to a folder
in your system folder that
contains the master sdef file
that tells the system how
an sdef file is supposed
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to be read.
Then finally there's a
pairing of tags for dictionary,
it's an open and close tag
for dictionary and we're going
to use this as our template for
creating a dictionary that works
with this command, transform
text how now brown cow
to upper case.
So I'm just going to leave that
on the bottom of the screen
as we do this so we can
keep in mind how this works.
Are you ready to go...here we
go, so the first thing I'm going
to do is insert within the
dictionary tags a new set
of tags called suite, I'm
going to create a script suite.
The opening tag to the script
suite has a couple parameters,
one is the name, I'm going
to call it text utilities
and a description, I
can give a description
and then a four character
code, Apple reserves the use
of four character codes
that are all lower case.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So those are used by Apple
applications like definder
to define their objects, you're
welcome to use any combination
of upper case and lower case
letters that you want that work
for you, in this case I
have four upper case letters
that I'm using for the four
character code for my suite.
Next I'm going to open up
this suite and I'm going
to insert a command, I want to
put a command in my script suite
and the opening tag
of the command tag pairing
has a couple of attributes.
The first is the name, that's
the name of the command
in this case it's
transform text,
so I want that to be
the name of the command,
that's what I'm going
to remember in my brain
when I write my scripts and
it gets and 8 character code,
commands are the only thing
that gets this 8 character code
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and the reason it does is
because the first four
characters are usually the code
of the suite that the
command belongs to followed
by an additional four characters
so that's what I did here.
Next we're going to open up the
command pairing and we're going
to insert a direct
parameter tag.
Now the direct parameter is the
object that we're addressing
in this case the text.
So it has a couple of
attributes in this tag,
the first is the kind of data,
in this case type is text
and then the description,
the text to transform.
There's no code necessary
because this is the direct
parameter of my command.
Once I've done that now I can
continue defining my...the scope
of my command by addressing
the second parameter here,
so I insert a parameter
tag in my command pairing
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and this one gets
the name of two,
it gets a four character code
and under type I
have case conversion.
Now case conversion is not
a data type or anything
in particular it happens
to be the name of the set
of enumerations that
I'm going to be using,
I'm going to create another,
another pairing later in my sdef
that will hold the enumerations
like upper case, lower case,
word case so for right
now I'm just going to type
in case conversion
and then that's it.
That's my basic command
tag right there.
After that I'll insert a pairing
for enumeration and this is
where I will list the various
enumerators like upper case,
word case, it gets a
couple of attributes,
the most important being its
name has to match the type
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that you just called in the
previous command so the type
for the parameter in the command
has to match the name of the set
of enumerations that
we're going to use
and it also gets its
own four character code.
Once I've created the
enumeration set I can insert my
first enumerator, it gets
a couple of parameters,
it's name is going
to be upper case,
it's gets a four character code
and then we can insert the other
two enumerators, lower case,
word case, each with its
own four character code.
That's the sdef that will
define the use of this command,
that's a fully formed
and correct scripting definition
file for having a single suite
with a single command that is
transform text direct parameter
to enumerator upper case,
lower case, word case.
This is what it looks like,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
if you saved this you
could just stop there
but you can do a little
bit of extra and I suggest
that you make that effort.
We're going to insert
in the command pairing a
documentation tag, an open
and closing documentation
tag and this allows you
to put information in
there about the command
so you can help somebody out
who's reading your dictionary,
you can tell them hey this
command is used usually
for this, this is how you
say it and you'll notice
that I've included a pair of 8
opening and closing HTML tags
in there and that's because
the dictionary viewer
in the AppleScript editor used
HTML to display the formatting
and the color of the
information in its window.
So that means that I can then
take some HTML and put it
into my documentation.
What I like to do myself is
always have an example script
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of how to call the command.
That's what I did
here, I have an example
that says transform text how
now brown cow to upper case.
So no matter what when the
user looks at the dictionary
for my library they can see
oh this is how you use it,
okay I got it.
Now when this is all displayed
within the AppleScript editor
application it will look
something like this, you'll have
your suite definition here then
you'll have the definition of
your command and how it's called
and then my documentation so
this is all documentation,
I apply text transformation,
for example change the case
of targeted text to upper case
and then I have a sample script
that the user can see and I show
them what the result typically
would be.
So it's worth it to add
that little bit of extra
in your scripting definition
file when you create it.
Now that we've done that we save
that file, we give it the name
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that we had for it,
AppleScript text utilities
and we just put it aside.
Next step is we create a
script bundle, very easy,
you go to AppleScript editor,
you open up a new file,
you go save and in
the drop down sheet
under file format you choose
script bundle as the format
that you want to use and then up
at the top you give it a name,
I'm going to call this
AppleScript text utilities
and you save it.
Once it's been saved we get the
access to the bundled drawer,
we open that up and then
again here is the panel
with all the various
options for us.
The script name, the
bundle identifier,
the short version number,
the bundle version number,
the copyright string, the
name of the sdef file,
whether we're using AppleScript
objective C, the contents
of the resources folder
and the little action menu
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that you can do things
in the resources folder.
So in this case we're
going to move the window
to the side a little bit and
we're going to actually take
that file and drag it into
the resources folder area here
and let it go.
This will copy that sdef file
into the script bundle for us
and you can see now
it has become part
of a list that's available.
Then I can fill out the
information up there
by checking the check box that
my using AppleScript objective C
and most importantly
put the name
of the scripting definition
file, the title of it,
in that field, you can leaved
off the .sdef then you simply
save your script bundle, close
the drawer and then save it.
Next we add the code
to the script bundle,
so we have our AppleScript
Library bundle
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and we've been using this one
handler over and over again
in Chris' examples and in
what I've been showing you.
But when you have a
terminology your handler has
to match the terminology
so you here we have an
AppleScript handler,
you can tell because it begins
with on and ends with in right
but the handler syntax has
to match the terminology
that I defined in my
dictionary so I begin
with my command, transform text.
Next I need something to
represent my direct parameter
so I have a variable
here called source text,
it's going to represent
whatever text is getting passed
to my handler, then my
secondary parameter two
and then another variable called
case indicator that's going
to represent one of the
enumerations that I created,
upper case, lower
case word case.
Let's take a look at how this
works again it takes the source
string, converts it to a Cocoa
string using NSString's string
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
method, string with string and
then based upon a comparison
between what you pass into
that handler for an enumerator
versus one of the other
options it applies
and instance method wither upper
case string, lower case string
and then finally we
convert everything back
to just plain AppleScript
text by saying
as text and we're done.
So this is the handler
that we're going to use,
we take our bundle we paste
it into it, we save it,
next we install it in
case you didn't save it
into the AppleScript
Libraries folder,
script libraries folder
just take the file,
make a script libraries folder
in your home library directory
and drag that script file
in there and that's it,
it is now installed
and now we can call it
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
so next step using the library.
So again we can just
target the library
with an AppleScript
Library identifier script
and then the name of the
library and we can encase
that within a tell statement
but this time instead
of calling the name
of the handler I can just use
my terminology, transform text,
here it is to upper case and
when this runs it runs fine just
like the other handlers
worked, it works perfectly.
So here's an example of using
that library in a script
for the finder, so this
particular script will change
the case of selected
folders in the finder
so if I have some folders
selected and I want their names
to be upper case this is the
script that will do that.
You can see that it runs
and the case changes.
Now I'll walk you
through it real quick,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
you get the selected items that
are selected and you iterate
through each one then we call
our script library, right here
and then we apply the results of
the transformation to the name
and then end our repeat.
So here's our tell block,
now there's a problem
with this tell block,
if I'm only using it once that's
not bad but if I have a script
that has to use this
all the time it's a pain
and in addition we have this
thing going on with variable
where I have to create a
variable to get the results
of the transformation that I can
then use later on in the script
because it's outside
of the tell block.
I want all of that to go
away and we fix that issue
with a new construct that we've
created called the use clause,
so at the top of my
script I enter the word use
and then my script
library identifier and what
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that does is dynamically
load my library
into memory making it globally
available throughout this
script, so I no longer need this
tell block addressing my library
and as a matter of fact once I
got rid of that I can get rid
of the nonsense with the
variables back and forth
and put everything on one line
so that the finder will talk
to this command transparently
and it all becomes
one single statement.
So we go from this to that with
the use clause, which is a way
to load and import terminology
into your script,
this is what we like.
Here's what it looks like
in an actual script window,
now with the use clause and
then taking out the back
and forth with the variable.
That's exactly what we
like, it's easy to remember,
it's powerful to use, it's
clean and it's a smooth syntax.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now when you deploy libraries,
once you've created something
like this you can put it
in multiple locations,
the one that we've been talking
about is your home
library folder
and in addition you can go to
the top level on your computer
and you can place it in
a script libraries folder
within that library folder.
If you have a script bundle
or a script application you
within its resources folder you
can create a script libraries
folder and place it in there.
So you can pass...give
someone a AppleScript droplet
or AppleScript applet that
contains script libraries
that it can draw from,
in addition any application
that's using calling AppleScript
you can create in its resources
folder a script library folder.
So AppleScript Libraries are
a new plug-in architecture
enabling quick development
and access
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to your favorite
sets of handlers.
It's different from
scripting additions
because you can write them
yourself in AppleScript
and they're controlled by
the script that loads them.
They can use AppleScript
objective C
to access all the
wonderment of Cocoa
and they can also publish their
own scripting terminology.
In support of them we created
two new constructs the script
library identifier, that finds
the library for you and loads
and we also created a new
use clause that allows you
to load the library
for global access.
So for more information you
can contact these poor guys
or watch the video from
the earlier session
on automation over view.
One more thing, this is a
very important day for us
because 20 years ago AppleScript
was given to the world.
[ Applause ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
In 1993 AppleScript released
to the...I mean Apple released
AppleScript to the public
and since then it's become a
phenomenal language that people
and companies rely upon
to automate the processes
that they do, they build
their businesses on it,
they build their
careers on it and we want
to take this opportunity
on the 20th anniversary
to say thank you to
all of the developers
that made their apps scriptable,
we want to say thank you
to all the scriptors who wrote
and write scripts everyday
and share them with others.
We want to thank our
customers for using AppleScript
and in addition we want to thank
all of the engineers that worked
on scriptable applications
and worked
at Apple in creating this.
We really appreciate
it, thank you so much.
[ Applause ]
[ Silence ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000