WWDC2001 Session 134
Transcript
Kind: captions
Language: en
okay welcome back the fewer the hearty
er the people without lives or families
to spend Memorial Day weekend with this
is part two of our AppleScript festival
this is building AppleScript
applications I'm Chris Espinosa the
manager of the components and scripting
group and we're going to take you
through some of the particular issues in
implementing your Mac os10 applications
some on just porting the application
over some on taking advantage of new
features and idiosyncrasies of Mac OS 10
it's a real nuts and bolts coding I'm
gonna spend a lot of time in project
builder going to spend a lot of time in
C code it will be cocoa free so I yeah
that always gets a mixed response what
you'll learn is how to port your
scriptable apps to ten which is
basically carbonised you know there's
really not a lot more than that a couple
of special issues what to do about the
FS spec problem which you may not have
run into yet but as soon as you do it
will be tragic how to deal with new Mac
OS 10 constructs like sheets I thank
Mark Aldred for bringing up both of
these to us he was the lone voice crying
in the wilderness on the Mac os10
implementers list
what about cheats what about FS specs
and we were so busy porting it to Mac OS
10 and getting the product out that we
didn't really get together and say you
know he's right this is a problem until
getting ready for this presentation so
we've got some fixes and how to debug
scriptable applications and and scripts
one of the greatest losses that people
feel in working on I want to go see what
they're doing over there they're having
a hell of a time maybe they're giving
away t-shirts one of the greatest losses
people feel in moving to Mac OS 10 is a
development environment is the loss of
Mac's bug and all of those great D
commands that help you know what's going
on in your system well we're going to be
showing you how to make up some of that
loss in this session so let's jump right
into it
you've got source code it's in project
builder you want to make it scriptable
how
you do it it's really very simple if we
could have demo one up this is our old
friend simple text which as you saw in
the last session has some scripting
capabilities it's got Apple event
handlers in it you know and it's got an
ability to execute Apple scripts but
it's not scriptable per se well we can
fix that
so if I want to take simple text and
make it scriptable it's a simple matter
of adding a file and yes we do want to
copy it in the new groups folder so we
add a terminology file and the
terminology file is our AE te as we know
it and love it
in this case though since this
application is a bundled application and
it has different variants and what I
have to do here is go to the target look
at the resources notice that it noticed
that terminology dot R doesn't have any
variants so I need to go back to the
files right there we go and pick
localization and platforms and add a
localized variant for English okay so
now terminology dot R has an English
variant that looks like everything else
and then I do a build and this is going
to do a complete build so it'll take a
little while really all you need to do
is add a terminology resource an apple
script will recognize the application as
scriptable if it has an AE T in it cocoa
applications have a special info dot P
list flag called NS AppleScript enabled
which is set to true you can go ahead
and set that in your info.plist even if
you're not a cocoa application that will
speed things up for us we'll recognize
you as a scriptable application more
readily if that's true but really all
you need to do is add a terminology
resource so here we go we've built now
we should have a simple text executable
and if we drag and drop this on script
editor
script editor shows us the simple tax
dictionary and if you launch simple text
and tell app let's see if we have a good
simple text document here
some users
[Applause]
there we go
there we go so scriptable simple text
that's all you need to do now when you
have a scriptable application you're
suddenly faced with the problem of okay
now I want to see what's going on and
project builder has a very functional
debugger where you can look at variables
and where you can step through
applications step by step but where if
you're used to looking at it in project
builder where you in code warrior where
you could format the variables in
different ways as characters or or
whatever or in max bug where you could
look at it in hex or ASCII as well as
decimal you'll find that there are some
inherent limitations in project builder
and its underlying debug engine gdb that
don't have the things you are familiar
with and really rely on in debugging
Apple events mainly because Apple events
are deep complex variable length data
structures that involve a lot of things
that are 32 bit quantities that are
interpreted by us as four characters but
aren't actually string or character
types and so gdb basically says hey this
is an unbounded long opaque data type
that has a lot of hex in it so I'm going
to show you the hex or maybe the octal
if you're lucky this is not very helpful
for debugging you want to look at four
character codes you want to find out
where your Apple event handlers are
installed you want to set breakpoints in
interesting places you want to look at
Apple events in AE desks and you want to
do do these all in your gdb environment
without resorting to the command line or
special tools well here's some help for
you first of all write these down and
memorize them they're very very handy if
you want to look at an OS type all you
have to do is cast it if you want to
print the value of a variable like the
descriptor type of an AE desk if you
just print desk dot descriptor type
you'll get it in hexadecimal if you want
to see what the four character code is
you cast it to a char for
and that will print it in the characters
if you want to set it you can set it in
gdb by saying set desktop descriptor
type equals but then you have to type
the hex or the decimal if you want to
set it as four characters you just cast
it to a star long star of a string the
string will essentially give you a
pointer to a temporary and then you cast
that to a long star and then you assign
that and then that will do the
assignment is for by quantity these are
two very helpful things to setting and
getting descriptor types or OS types in
gdb breaking if you want to set
breakpoints you can set breakpoints in
the Apple Event Manager that will be hit
before the Apple event is dispatched to
your application this is especially
important with the Carbon event model
with the Carbon event model you don't
usually have a place where you call AE
where you call AE process applicant
Carbon just dispatches directly to you
so if somebody is sending you an apple
event and none of your handlers are
getting fired how do you know there's no
bottleneck in your code to set a
breakpoint on well you can set a
breakpoint in the Apple Event Manager
okay
okay now I'm at a EEM dispatcher this is
right and at am dispatcher register
three is the pointer to my Apple event
and if I look at it in hex it's six one
six five seven six seven four and then a
short hex value which looks like a
handle so that looks like an AE desk and
that's that's great except it's hex so
let's use the trick I used before which
is print casting to char for a
dereference of dollar r3 and it says
it's a EVT yay
so I know it's an a EVT okay but let's
leave this here for a while go back to
the slides because now the problem is
okay I want to see what that Apple of it
is and how do I know what that Apple
event is well I could go in and I could
dereference the handle EE and then
examine memory from there and poke
through it and I might see the the event
class and the event code and then the
parameters might be in there and if they
happen to be an ASCII I could probably
figure it out but that's not very
helpful and Eva kersky wrote for us a
great dekum and in max bug called AV T
which will dump it all out but we don't
have that in gdb so what we need to do
is write in short gdb script and one of
the good things about gdb and I know max
bug can do this too is that gdb can
actually call library functions from a
gdb script so what we're gonna do is
we're going to call a eprint the AE
helpers routine that takes an Apple
event and turns it to ASCII and we're
going to do some things like calling
malloc to allocate temporary memory
which we have to deallocate and then
we're going to put this all in the
script we're going to put it in our home
directory and then we're going to invoke
it from the command line
and this is basically what our script
looks like it's got a ePrint desk to
handle and then a printf in it and then
a couple of dispose statements so we'll
go back to the demo machine let's take
this and put it in my home directory and
then in project builder
slide down the debugger this is what the
GD BAE desk looks like just like on the
screen so let's go back to where my
breakpoint is and I'm going to type
source till this last gdb a e desk and
then just to confirm that it loaded I'm
going to type help user-defined okay and
it says list of commands AE desk and 8u
get Apple event handler
those are two very useful things that
are defined in that so now I can type a
EE desk dollar r3 and it'll chug for a
while and it tells me that it's an AE V
T it's an OE pp and it's being sent to
this PSN and there are no parameters so
I'm using the AE print function in AE
helpers from a gdb script in order in
the at a debugging breakpoint in the
Apple event manager to see what my
incoming Apple event is this is going to
be very very helpful for you in
debugging your Apple script applications
similarly if you want to know where a
event handler is installed if you don't
know where your code is there's some
code here it calls actually the app
actually the actual Apple event routine
a you get event handler you pass it to
strings for the event class of the event
code and it'll tell you the address of
the handler and then you can set a
breakpoint on that and then you will get
a break when that handler files fires
this is very handy for figuring out you
know when a particular handler handler
fires especially if the handler is a
wild-card handler okay so with the
preliminaries done let's talk about the
difficult stuff special topics for
coding for Mac OS 10 things you may not
have anticipated or known about in
making your application scriptable we're
going to talk about a minor
housekeeping note is a change in the
Apple event handler prototype which is
going to involve you changing some year
code we're going to talk about FS specs
we're gonna talk about sheets and we're
gonna talk about loading scripting
additions into your application
okay the Apple event prototype change
this is something really unfortunate but
we felt we had to do it and the Mac os10
transition was a good time historically
Apple event handlers have had a refcon
like Windows have ref cons and controls
have ref cons Apple event handlers have
had ref cons and historically that
refcon has been assigned long integer we
noticed in putting together the headers
for Mac OS 10 that all of the other ref
cons in the system were unsigned long
integers all the others all the other
ref cons are signed historically the
Apple event handlers had been unsigned
we decided to fix this and fixing this
means that you're going to have to
change the prototypes on your Apple
event handlers and the and the headers
on the handlers and the but not the
installation code it's otherwise you
would have to do a lot of casts it's not
pleasant but it's just something you
have to do it's it's just some
housekeeping but I just wanted to let
you know that that's coming up more
serious is the issue of FS specs F
aspects have been pretty much the hard
coin of talking to the file system since
people really started using the the new
file system calls in in Mac OS 8 FS
specs have been fairly useful they let
you get at things in the file system
without having to deal with paths but
there are some problems in Mac OS 10 FS
specs first of all are limited there
their path name is HR 255 and it's
intended to be in the system encoding
and that means that an ephah spec can't
really refer to a long file name or
refer to a Unicode file name very well
we're strongly recommending you you work
with FS refs that can do this but FS
specs have a fundamental limitation but
there's a problem if s refs
can't refer to non-existent files and FS
specs can and the reason why a lot of
people like FFX is that you can use them
in creating a new file and that's
important in Apple event Apple scripting
application where one where a script may
want to tell a application to create a
new file you want to some compact useful
way of saying what new file to create
and an FS spec can't do it because it
can't use long Unicode file names and
then an FS ref can't do it because it
can't refer to non-existent files what
complicates this is that in the carbon
model each carbon application has its
own view of the vcbq that means each
carbon application has its own list of
volumes that may be in a different order
so a volume ref num is not valid across
processes that means that an FS spec in
an ffs ref which our volume ref numbers
are not valid across processes so you
can't really legally send an FS back or
an FS raft from a script to an
application because it's volume list may
be different and it may be talking about
a different volume we we get these bugs
every once in a while I wrote this
script and I told this application to
save the file
but it's saving it on a different disk
why is that well it's saving it on disk
negative - and in that application disk
negative 2 is a different disk than in
that one if you're lucky it works if
you're not lucky and you're going deep
down you probably don't have the same
directory structure on each disk that
the derp IDs are probably not the same
and it just plain doesn't work so we
need a solution to this if you want to
send a save event to your app if your
application wants to process a save
event you need a way of getting the file
name that's not FS ref or FS spec based
well the answer is you know whenever you
can you use type alias if we're open or
for print events or for anything else
dealing with a file type aliases are
valid across processes and they can
represent long Unicode file names but
they too cannot represent non-existent
files so for non-existent files
we are creating a new type called a type
file URL and the date of a type file URL
is the same format as the eff URL drag
flavor
if the finder drags a file to you using
the drag manager and drops it on you
when you get it out
you probably coerce it to an FS pecker
in FS ref and then you get it in your
context but inter-process it's being
sent as this F URL data type and this F
URL data type is process independent it
can refer to non-existent files and it
doesn't rely on volume ref nums so it's
legal to send across processes we're
going to use the same data format with
the same four character code to specify
new files in Apple script what's nice
about it is that it is filesystem
independent it encodes special
characters so you can have a file name
with colons or slashes and you don't
have to parse them out it can
distinguish between files on volumes
that have the same name which is really
important and it's valid across
processes and boxes and since it's a URL
it's even valid across machines really
we're gonna provide you with some sample
code george warner and john Montreat
Briand are working on this now we're
providing a few routines to basically
create and extract file URL data types
from things that you see every day from
nav services replies from IE desks to
get them in and out of Apple events and
also to create a new file given an F URL
in one step rather than having to take
it apart and find the file name portion
the directory name portion and call the
FS create Unicode call so we're just
packaging this up as a bunch of sample
code we're also providing coercion x'
between this F URL and all of the
interesting types all of the interesting
character types type chart type style
text type Unicode text so that users
could see these if they wanted and they
can create them and all the type files
the the C file object specifier the type
F SS
and type FS ref a aliases and the object
specifier of course so that people can
actually compile these in Apple script
so how you use these is very
straightforward say that you are an
application that is factored and you
send yourself a save event so after
somebody chooses save and they fill out
the nav reply record you want to
generate a save event with the file name
that's been picked in the nav reply
record and send it to yourself to
actually save the file
well the nav reply record gives you a
directory URL and a CF string of the
unicode file name those aren't very
useful to you when you want to get them
into an AE desk so we've created one
call that takes that nav reply and makes
it into a CFL the underlying core
foundation URL datatype and then another
call that puts that CF Earle into an
apple event as an F URL parameter and
all you have to provide is the key so in
basically three lines of code you can
take your nav services reply and stuff
the fully transportable file name from
that into an outgoing apple event
similarly on your save file apple event
handler you're going to get an in
parameter in and it can be anything it
can be an alias it can be an FS spec it
can be an FS ref it can be a type file
Earl but you want to you basically want
to know two things one does is does it
already exist and if it doesn't already
exist how can I make a file that does
exist so I can write into it and get an
FS ref from it and so basically what you
do is you get the the in parameter as
you try getting it as an FS ref if that
fails then either there wasn't something
there or there was something there that
couldn't be resolved to a file that
exists so you guess okay if my FS if my
FS ref succeeded I'm writing to an
existing file if it failed I probably
want to create a new file so then you
try to get the in parameter as an Earl
and if that succeeds then you know hey
I've got this reference to a
non-existent file and we you call one of
these other sample code routines URL
create with CF URL you pass it that Earl
and you get back an FS ref of the
brand-new created file and then you can
proceed as as normal so what we've
worked to do is provide sample code that
not only demonstrates how we do it but
is very easy to use in the common
application which is create an apple a
send Apple event to send to yourself and
receive a send Apple event and process
it so now I'll show you how that
actually works once again in simple text
the first thing I want to do
is add and include
for my dot H file and add that dot H
file
and that's going to be this here's my
file early Sh
so it didn't copy it so it didn't add it
so let's not copy it
okay so here's my dot H file
and basically it defines a create from
nav apply create desk from SIA URL put
for am and put key CF URL create one
from a desk create it from an Apple
event parameter create it from a record
key created from an FS spec create a new
file with an Earl and then a couple of
coercion handlers and one of the things
we want to do is we don't want to
install those coercion handlers so let's
get the source
okay
now I want to add a save event handler
and we're going to call a save event
handler and see how this does it so I'll
go open up my add-ins and I've got a
save apple event handler julia child
format already canned and I'll go to
where I should add my save event and
paste it in and I'll go back and install
my save event handler this is the code
to do that and then install a couple of
coercion handlers so that I can process
a few RL types coming in I'll copy those
and I will add them right in here okay
and then I will build
while that's building what I'll do is go
to my home library scripting editions
folder and I'm going to copy in a
special version of standard editions
which has a version of choose file name
which has been updated to return F URL
and we'll see this in the event log and
we'll quit the script editor just for
fun and we'll put simple text just to
make sure and our build has succeeded
so now we'll run
and we'll open up this save as example
and so this is fairly simple this is
what you might see in any script set f2
choose file name save document 1 in F ok
but normally choose file name would
return you a file specification and
you'd send it to save but now we're
sending it a F URL and the F URL will
result in a new file so we'll turn on
the event log so we can see exactly
what's happening run it choose file name
ok so notice that it said save document
1 in file URL file : / / localhost /
user / SBC h / document / baz text ok so
instead of an FS spec it came across as
a URL notice that simple text saved it
as vas text and when we go back to the
finder and go look in my home directory
in My Documents folder there it is so
this is an example of how you can very
simply without really changing your your
application architecture just use a
different data type in this case this
the the F URL data type to get around
the problem that FS refs and FS specs
can't be sent in Apple events as I said
we're working on the sample code for
this it's going to be released as a tech
note and you'll have access to this to
incorporate into your applications the
coercion handlers that I talked about we
will incorporate into a future version
if you want to ship something now for
Mac OS 10 point 0.3 you can install the
coercion handlers yourself in the later
version of the operating system when
they're already installed you can either
continue to install them or just stop
installing them and you'll inherit the
ones from the system so what this means
to you is that with this sample code
it's safe and probably important to
remove all type FS specs from your
scripting interface if you're doing
Oh Sachs's oh s--- accent if you're
doing factored applications if you're
doing send to self applications you
should probably not send yourself FS
pecs you should probably not expect to
get FS pecs or FS refs from other
applications you should really migrate
to this new data type it's the same one
that we use in the drag manager its URL
base there's support for it in core
foundation we're providing sample code
for you to do it it's something you
should really look at migrating to the
second issue in Mac OS 10 is handling
sheets sheets are window modal dialog
boxes and as window modal dialog boxes
they behave differently than dialog
boxes do on Mac OS 9 Mac OS 9 dialog
boxes are application modal they block
the whole application so that when a
script tells you to put up to do
something and you put up a dialog box
that script halts because you won't send
back a reply apple of end until that
dialog box is dismissed in many cases
this is what users what scripters want
because it mimics the user experience
the problem is with a window modal
dialog box your application doesn't help
what happens is that you get an Carbon
event in and you show the sheet and then
your Carbon event handler exits and then
your application is just running and the
sheet is going to be called by a
callback a sheet of n handler and then
you install a procedure on that to
actually do what the sheet does whenever
it's dismissed so you basically have
these two threads of execution one is
the the main event handler and one is
whatever happens when your sheet event
handler gets called well if you mimic
that with an apple event handler what's
going to happen is that the Apple event
will come in it will pull down the sheet
and it will return without an answer
because the user hasn't filled out and
okayed the sheet yet ok if this is like
a save dialog box
the
you won't know whether it actually got
saved if it's a if it's a sheet that
says this document has not been saved
you are you sure you want to and the
user presses cancel you know maybe you
want to return a user cancelled error
from that rather than just say oh it's
okay
because basically your script will
continue executing and it will continue
executing on the assumption that the
previous event has been fully handled
when in fact it hasn't it's still
waiting there for user input bad things
can happen so there are there are four
solutions to this the first one is the
easiest way and it's probably the best
way is to always provide a way from your
scripting interface to let the script er
avoid pulling down the sheet that's
going to be the safest if the script err
can provide all the information that's
supposed to be in the sheet in the in
the event and you can avoid pulling down
the sheet altogether and just process
the event do that it's the best safest
way but what if there are cases where
you have to pull down the sheet or if
the scripture actually wants you to pull
down the sheet and have user
intervention such as the shut down the
entire system event you don't want to
prevent the user from having the
opportunity of saving open documents in
that those sheets really have to execute
and you don't want the shut down the
system event to say okay I'm done and
shut down the system while all these
sheets are pulled down waiting for users
to save files it's not the right thing
to do so the wrong way is to just return
even with the sheets are still down your
script and your application will get out
of sync your script will continue
executing it'll keep firing events with
the assumption that say that window has
already been closed or that document has
already been saved or it may go look for
that document in the file system now
even though it hasn't been saved yet and
it won't find it and it'll be an error
you don't want to do that the cheap way
is to see if you're pulling down the
sheet based on a user action or from an
Apple event and if it's being pulled
down from a user action make it a sheet
and if it's not make it application
modal
and if you make it application modal
it'll behave like mac os9 it'll block
the application that's a cheap way to do
it it's effective it's really easy to do
with sheets it's fairly easy to do with
nav Navy I logs there's just actually
one bit you set a nav dialogue to say
make this app modal rather than making
it window modal and it does the rest for
you it it'll work doesn't provide the
best user experience the nice way and
the way that works if you really want
your scripts to be able to pull down
sheets and wait for user input before
resuming is you have to suspend the
incoming Apple event and then resume it
when the sheet is dismissed and let me
let me show you how that works so
somebody sends a close Apple event to
your application you create the sheet
you install the sheet event handler you
show the sheet and then you suspend the
incoming event and when you return from
the Apple event handler you don't return
all the way it doesn't fill out a reply
and send it back to the original
application it leaves that application
hanging fire until the reply is actually
filled in this is the behavior you want
because if this is coming in from an
external script that external script
will just think gee it's taking a long
time to process this event and maybe
it'll timeout if it's got a long time
out it'll wait the right thing happens
then your sheet event handler when
somebody actually does click a button
you hide the sheet you dispose the sheet
you get the information about what they
actually did you maybe put that in the
reply and then you resume the Apple
event and at that point the reply Apple
event is actually delivered to the
caller and then the script says oh this
is what happens and then execution
proceeds and then in your process then
you can hide the window and dispose the
window and do everything you want and
then your sheet handler proceeds well
you want a special case that because you
don't want to hang yourself while
waiting for a sheet application to occur
so basically in your window event
handler if somebody clicks the closed
box or chooses clothes you can create a
Apple event and send it and then your
Apple event handler has to notice hey
this is sent to self not sent from
somebody else there's nobody waiting on
me I'm just going to execute and return
I'm not going to suspend the event and
this is the crucial part if the events
coming from outside you suspend it if
it's a send to self event you don't and
then similarly in your sheet event
handler if there's a suspended event you
resume it and if there's not you don't
makes kind of sense because if you try
to resume and there is no suspended
event well it doesn't quite work so
going back to sample code
I have here I took the sheets sample
code from DTS and hacked it up fairly
majorly to make it scriptable editing a
bunch of events but you can see that
I've added Apple event handlers for you
know open and reopen and open doc and
I've added a Apple event handler for
make a new window and this creates a new
window and then in the and I've also
added an Apple event handler for cloak
to close the window okay and in the
carbon event handler here is the carbon
event handler for closed
basically what I do is I use the very
convenient
AE helpers to build an apple event and I
build an apple event that says closed
saving ask and I send it to myself and
so when I click the closed box or when I
choose closed from the menu I'm going to
generate an apple event which is good
for recording purposes and then I'm
going to catch it in my closed Apple
event handler okay well let's look at
what happens I have a switch in here and
right now I'm going to handle it just by
returning and I believe that this is
already built great so if I run this
application it comes up and nothing
happens and let me open this little
script and what this script does is it
makes two windows closes one saving ask
and then uses a speech generator and I
hope the sounds working to say I'm done
with the script if sound isn't working
just watch the stop button so we run the
script I'm done with this cream now it's
done with the script but the closed
operation hasn't finished okay and in
fact the applications still live and I
could cancel this or I could close a
different window but the script is
already preceded on the basis of the
understanding that the first window was
already closed okay this is this is not
the behavior that we want
so let's quit that and let's go back to
our switch here and say handle by
suspending okay and let's put a
breakpoint at suspend the current event
and a breakpoint okay so
now we only have one scriptable sheets
great and it's bouncing and it's running
so we run and we hit our suspend
breakpoint okay now let's and our script
hasn't terminated yet so we go back to
scriptable sheets we click okay we hit
the resume breakpoint I'm done with this
cream and then we're done with the
script so this will be releasing a
sample code too it's fairly
straightforward there are a couple of
complications though if we could go back
to the slide the one thing I talked
about before is you don't resume the
send to self events that it just doesn't
work don't do it the second interesting
thing is if you have a coding style
where you if there's an Apple event
error you propagate that through up to
upper levels it's really interesting in
your Carbon event handler if your Carbon
event handler sends Apple events and the
Apple events receive errors don't
propagate those errors back out of your
Carbon event handler because what will
happen is that carbon will dispatch that
back up the carbon calling chain so you
need to be intelligent about the
relationship between your Apple event
handlers and your Carbon event handlers
and understand that if an apple event
because the when you suspend an apple
event it actually returns a timeout
error to the caller so if you're sending
well you need to work out the
relationship between your Carbon events
and Apple events and not send things
back up the chain because carbon will
reduce patch it and then you will get
several invitations of the same event
which is not what you want in this case
you get two sheets on one window which
is not good if you're an attachable
application there are a couple of things
to make sure of you want attached
scripts to behave like external ones in
that you want the scripts to pause but
when you're executing the script the
events are being sent sent to self so
your simple case of if it's coming from
outside
it's a script I suspend if it's coming
from inside its a factored command I
just executed that doesn't work but you
can't suspend it because it's sent to
self so what do you do well in the case
of if you're executing a script that is
sending yourself commands what you need
to do is execute that script on a thread
and have a send function for that script
execution for that call to OSA executors
or execute event that blocks that thread
until the event returns and that's
essentially the way to suspend and
resume that of end execution under your
control rather than the Apple event
manager control and then you unblock the
thread in your sheet handler that there
not a lot of attachable applications
that are going to be scripting Saveur
things with sheets if you happen to be
in that case and mark wanted to know
about this because he is this is how we
think you should do it so what this
means to do to you if you adopt window
modal dialogues if you adopt sheets or
the sheet style nav dialogues you have
to change the way you deal with event
handlers you pretty much have to go to
the Carbon event model it really helps
to go to the Carbon event model and you
need to plan the relationship between
your Carbon event handlers and your
Apple event equivalents let me do one
quick thing about scripting additions in
Mac os10 from the programmers point of
view I talked about from the users point
of view of where you put them and how
you invoke them from the programmers
point of view you don't get scripting
additions in your application unless you
make an OSA call in which case you do
but what if you wanted to get scripting
additions and execute them in your
context and you don't want to have to go
over the over go through the overhead of
starting up Apple script in order to do
it we have some following magic stuff
read quickly basically you grope our
library for a special symbol called OS a
install standard handlers if it's there
you call it and then you send yourself a
special event called the GD ut event
this is the event that Apple script
sends to load scripting additions and
when you send this to yourself then
it'll load all the scripting additions
into your
titian you only need to do this if you
really want scripting additions to
execute inside your application space
inside your application process and you
don't and you're not going to execute an
Apple script yourself it's a fairly rare
case we generally don't recommend
groping our frameworks to find private
symbols but this is a fairly safe one
you're only calling it if it's there and
in the future if we if we do this
differently we'll remove that symbol and
then your test will fail you won't do
anything everything will just work fine
in the future they may be loaded into
every application by default we're still
looking at that there are some security
implications to that we definitely don't
want people sending for example terminal
or login window events that get executed
by secret scripting additions that they
put in the network scripting additions
folder and all of a sudden they get root
privileges and can write all over your
machine we need to look at that model
before we execute scripting additions in
every applications there are
alternatives and one of the alternatives
is great third-party product called
script debugger and Mark Aldrich is
going to come up and show you how you
can use scripted debugger to debug
scripts executing inside your
application mark
so I'll start by showing you a few
features of script debugger as a just an
apple script debugger so you can see how
your script might execute what I have
here is a little FileMaker database with
with a picture and some text and a
script that that works with it excuse me
so what this script does is essentially
read some data out of this FileMaker
database and do some stuff with it
script debugger gives you all the
standard debugging things you need
breakpoints and other sorts of things so
let's just do some execution as you go
variables come into the browser you can
hover over a variable and examine its
value you can run to a breakpoint script
debugger shows you the scope of all you
of your variables as you go anything
that has a white background if global
anything that has a yellow background is
local to this function or handler in
Apple script terms and anything with a
blue background is built-in to Apple
script itself one of the things you can
do is if you don't like the way the
browser operates or you want to see
something you know in a larger view you
can open us a separate window and you
can view it in a print form as the
source code from Apple script or in best
and one of the cool things about best is
that it allows you to deal with things
other than textual data so for example
as this script reads pictures and text
the debugger shows you the actual live
data
[Applause]
now if you're trying to debug a script
running within your own application you
need to be a scruffy bugger gives you
the ability to actually invoke that
debugger from your context not just the
script debugger application and the user
interface for this is is simply
switching OS a languages so you switch
from Apple script to Apple script
debugger and save your script in this
instance it's an applet and then when I
drop a few files on there the applet
launches as it normally would and then
script debugger comes forward and you
can actually see exactly what your
applet received from the finder which in
this case is a pair of aliases and bear
with me it's still beta you can step
along
examine all the things that are going on
the key element here is that if you if
you support what's known as the generic
OSA component in your application if you
have a script menu or any other setting
in which you X set a setting in which
you would execute a script apples the OS
the generic component will automatically
load the appropriate language and by
doing so you let the author of the
script
[Applause]
you let the author of the script make
the choice and in this instance they've
chosen the debugger but they might
choose the OS v the UNIX shell OS a
component that Kris was demonstrating
earlier on and so with that simple
switch of a language the debugger can be
executed inside your application and you
can see exactly what you're doing and as
sort of the final example of how cool
that might be
[Applause]
so there you can have the debugging
running inside the show thank you very
much great thanks mark
so Mark's done a lot of work over a
period of years trying to work around if
we could have the slides back the fact
that Apple script doesn't have any
system level debug api's and we're
trying to rectify that and work with him
and the developers of other debugging
applications if we could have the slides
back to actually put in some debugging
api's into apple script so that they
could take advantage of them and you
could take advantage of them in your
applications or invoke them from gdb for
example to find out what's actually
going on inside your application when
you're executing scripts we have a
framework for what the API is look like
the basic contact concept is that
there's a debug session which is based
on OSA IDs and there are stack frames
and you can walk the stack the stack
chain and look at Global's locals and
properties of a handler or a script in
this stack frame that looks like it'll
have a good match with the user
interface of the current debuggers and
also all the things that you may want to
do from inside the script also providing
an interface to break and single step
and step in to step over continue all
the things you'd expect from a debugger
the important thing is that it needs a
remote mode as well and that remote mode
will of course be via Apple events so
that you could send them from your
debugger you could send an apple event
to any executing application executing a
script to halt that script application
and then have the entire debugging
transaction over Apple events this would
be very exciting when we've got Apple
events over the Y over the internet
again because you could do remote
debugging over the internet between two
machines on Apple script we're really
looking forward to that and we're
working closely with the developers of
debugging applications so to summarize
everything you need to make a good
scriptable application
both an application that implements
script ability and an application that
executes sappal scripts is in carbon
framework now and there should be
nothing holding you back from developing
great scriptable applications if there
is let us know it's easy to invoke
scripts from your code I mean simple
text does it in the demo it's three or
four lines of code and if you do make
sure that your OS a component agnostic
so you can take advantage of things like
the OS a script the shell scripting
component or the
or mark Aldrich the debugging component
so that if you execute scripts you don't
just execute Apple scripts but you
execute any scripts because we'll be
widening the the range of scripts in the
future make sure you migrate away from
FS specs because FX specs are not the
right way to send things between
applications please adopt the sheet user
interface in aqua and take the ways
we've shown you to make sheets work in
scripts and use the development tools
project builder is a very effective
development tool for developing testing
debugging and deploying your application
there's only one more thing left to do
and that's the feedback forum which is
going to be across the hall because we
have sixteen fifteen fourteen seconds
left we're not going to take any QA here
but we'll take any in the feedback forum
once again Jason is the technology
manager contact him I'm the engineering
manager used lists George Warner's our
fine tech support
you