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