WWDC2001 Session 114

Transcript

Kind: captions
Language: en
when I welcome you to session 114
application packaging and document
binding and this morning at the end of
my session 111 I was talking about how
you know some of the things that you
need to do to create a great user
experience on Mac OS 10 and one of the
things I mentioned was you know bundling
your application so we want to talk here
in this session about how to package
your application and bundle it with the
differences between those two terms we
want to talk about document binding what
are the rules for for Mac OS 10 and how
documents are associated with
applications and this is something you
need to pay close attention to it's
something that's been discussed a lot
online with some of discussion lists and
we would like to clarify a little bit
what needs to be done from the
developers point of view so to talk to
you through this material I'd like to
explain this material to you I'd like to
introduce Christopher Lin from the user
experience engineering team at Apple
[Applause]
good afternoon almost even
it'll be evening by the time we're done
hopefully not too late into the evening
I've got a lot of slides a lot of
material in fact both of these could
probably have their own session but we
wanted to cover them together packaging
and binding because they are closely
related and let me see if I can get this
to work
okay so first half of my talk is all
about packaging how you deliver your
applications on Mac os10 and I'd like to
talk a little bit about what the
traditional delivery mechanism is or
structure of an application and then
look at this new choice sometimes
usually called a package sometimes
referred to as a bundle I'll try to
explain the difference between those two
terms and then really going to some
amount of detail of how an application
package is structured and look at some
of the important internals such as the
property list and how you express things
like what types of documents your
application can open and what types of
URL schemes your application can handle
then in the second half I'd like to go
into document binding in which we talk
about what exactly does document binding
mean
how does it work on Mac os10 and
therefore what guidelines should you
follow when saving new documents from
your applications finally I want to give
a quick overview of what the capability
of this new API is called launch
services that essentially provides the
binding service on 10 excuse me and look
at how you can make sure that your
application once it's installed is
actually also in the bindings database
okay
so let's start out with something simple
what is an application well of course
it's a big hunk of code a big program
you've been working on slaving over for
several years probably fine-tuning it
and adding features but in order for it
to work there's a whole bunch of other
stuff that needs to go along with it
localized strings controls and view
system view layouts icons and images and
help files plugins and I could go on and
on and all these things are really
necessary for your program to run so you
want to make sure it all stays together
I call all this extra stuff the goo with
your application the goo needs to be
there or else your application won't
work the way that applications have been
traditionally packaged has been with us
since 1984 the original Mac OS
introduced resource files and in fact
everything was in the resource fork back
then the code and all of the extra goo
and it presented this great single icon
view of an application to your users it
was very clear to run an application you
double click that icon I had some other
advantages and that non-programmers
could get in with localization tools and
create a localized version of your
application and this format is still
fully supported four-carbon applications
on Mac OS 10 but there are some
limitations not everything can
appropriately be placed in the resource
fork or the core resource file and so as
I forgot his applications have gotten
more complex over the years
you see that sometimes you look in a
folder and you'll see a lot of other
icons there and some of this stuff might
be necessary for your application to
function property some of the plugins
for instance and in addition it's just
more complex for the user because the
user has to like find the right icon in
order to double-click and open your
application correctly
another problem with this model is that
when you localize a single file
application it only has a single
localization in it so you may have to
make an English version of your app and
then a French and the Japanese version
and so on a separate version with your
with your binary duplicated for each one
and and so it's just some extra work and
more complexity for for installs and in
addition that once the user installs
your app it can only run in that one
localization so what we want to get back
to is the simplicity that looks like
this one icon it's an application the
user knows what to do and you
double-click it and so what we're
introducing is application packages a
package is simply a directory that to
the user looks like a file what goes
inside there is completely up to us
Apple defines a certain structure you
can extend that structure by or work
with it it's it's fairly flexible as to
what goes inside there and it can grow
over time without impacting the user the
user will always see just this nice
simple view all the goo is hidden inside
there's some other great benefits of
application packages you can have
multiple binaries inside so for instance
you might want to set up your package so
that it has one binary for Mac OS 10 but
it has a classic binary in it that can
actually run when the package gets
double clicked on Mac OS 9 and we'll
talk about that but I think the most
exciting thing about application
packages is how they can contain
multiple localizations as many as you
want
and this means that you can have a
single install of your application and
it works great on a multi-user system
we're one user logs in and prefers one
language double clicks your application
that's the localization they get the one
they prefer a different user comes in
speaks a different primary language they
double click the same package and they
get the localization that they prefer
the language that they prefer finally
although I'm not going to talk about it
much today packages are not just for
applications it's actually possible to
define document packages and that's
something that interface builder uses
but mostly I'm going to be looking at
application packages today
interchangeably you might hear me using
the term bundle and package and I'd like
to try and clarify once and for all
maybe what the difference is and the
reason I use the terms interchangeably
during this talk is that you can see
right in the middle is an application
package it's both a bundle and a package
on the Left we have something that's
just a bundle and the example I have is
a framework a bundle is a directory that
contains code and some associated
resources or goo but it's just a
directory okay if it's just a plain
bundle like a framework you can actually
click on it and look inside it you see
the contents and the reason we didn't
seal it up as a package is that there's
actually some headers in there that we
want you to be able to get at easily on
the other side is something I call a nib
package it's actually usually usually
referred to as a nib file so you may not
even realize it but a nib that is
produced by interface builder is
actually a package and a package means
one thing it's a directory that is
presented to the user as the file so it
looks like a file to the user in the
middle again you have applications and
as we go into the application structure
I'll try to point out what things about
are specific to bundles and what things
about it are specific to packages so
this is a quick overview of what the
structure of a package is inside at the
top level this is a sample application
on the developer CD called
sketch
and basically inside at the top-level
package there's actually just one thing
another folder called contents so Apple
chose to take all of its structure and
put it in one place so that it doesn't
conflict with anything you might want to
do up at the top level and really
everything interesting about the
structure is inside or the contents
folder the first thing is the property
list this is something that all bundles
have a property list it's a file called
info.plist
and it tells the system it's in the
format that the system understands and
it tells us all about your packet excuse
me all about your bundle and we're gonna
get into that and in a fair amount of
detail so for right now let me just go
on next is another directory called the
resources directory and this is where
all of the goo goes all of your
resources whether they're resource files
or strings files or images icons
anything goes in the resources directory
and there's two parts to it up at the
top level of the resources directory if
you will go all of your resource files
that are global that don't need to be
localized and then for each localization
that you want to add to your package you
have a subfolder which is named after
the language for that localization and
the language names are are defined by
the core foundation bundle api's and so
you can have as many of these as you
want English French Japanese and so on
and inside here is where you put
resource files localized strings
anything that needs to be localized goes
down in here and there's one file in
particular I want to call out and that
is a file called info.plist dot strings
it turns out that some things in the
property list up at the top level there
are in the contents folder are actually
user visible things like the the user
visible name of your application and the
the kind strings associated with your
document those things need to be
localized so there's a part of your
property list that lives down in each
localization folder and that's in a file
called info.plist on strings and a
strings file I'll show you a little bit
later but it's basic
just a set of key value pairs that we
can do a look-up on to find an actual
value for a string okay back up to the
contents folder the next thing is this
pkj info file if you look at it in the
finder you'll see it's always 4k well in
fact that's the minimum block size and
you look at it in detail it's only eight
bytes large this is the contents of it
actually are not public but if you look
at it it's obvious that it's the type
and creator of your package since since
directories don't actually have types
and creators associated with them in the
catalog info of the file system this is
where we cache it and it's basically an
optimization you don't need to worry
about this file except to know why it's
there its presence helps us know that
that this is in fact a package and the
contents may change in the future as as
we need necessary and finally we get to
where your executable lives on Mac OS 10
when an application packages is launched
the system always looks in a directory
called Mac OS with no space even though
marketing would rather it have a space
it's not actually user visible so we
just simplified it and in here is where
you put your binary and in fact the name
of the binary can be anything you want
it never is user visible however in
order for us to find it and it needs to
be specified correctly in your property
list so that is a simplified view of an
application package structure and I'd
like to touch on one other topic related
to the structure and that is about
packages on Mac OS 9 so I'm going to
strip away all that other stuff about
property lists and resource directories
because Mac OS 9 doesn't have any of
that infrastructure but we did want to
give a minimal way for Mac OS 9 to
recognize and launch packaged
applications obviously it's not going to
be able to launch the Mac OS 10 version
because it can't get it the resources
down in the resource of directory but
what you can do is create another
directory to hold your classic binary
and this is this is actually a single
file traditional
Mac OS 9 application it's got to have
all of your resources in there localized
to one particular localization and the
way you get Mac OS 9 to launch it is you
create an alias and actually the alias
can be called anything because we just
look for an alias any kind of alias
inside the application package and you
make that alias resolved to your binary
and the mac os9 finder will be able to
launch a package like this so this is
one way if you really want to get on the
package train and take advantage of all
the advantages for ten you can still
have a single package which can be run
on Mac OS 9 and now I'd like to switch
to the demo machine here and just show
you a little bit about packages live so
sketch here is kind of a sample app I
was going through and it's a cocoa
application that does some simple
drawing and see should I close it and
quit and we kind of struggled with
whether or not we wanted to do this in
the finder but turns out that it's
really handy to be able to have a
backdoor to get into a package when you
really want to inspect the contents and
so what we did was we put it down in the
contextual menu so if you control click
on a package there's actually command
cícero package contents and this is so
you know it's there in case you need it
here we have the inside of the package
it's a window that's actually rooted at
the package it doesn't go up to the rest
of the hierarchy but it is a regular
Finder window you can change say to the
list view and let's take a look inside
here is the property list the Mac OS
directory with the binary in it the
package info file and let's see in
resources we have a whole bunch of stuff
actually we've got TIFF files and icons
and then here we have some localizations
English Japanese and even Klingon there
it's one of the advantages of Unicode
that's and then in here we have nib
files that get localized and here of
course is the info peeler strings file
which contains some of the localized
information from the property list so
that is inside a package in the finder
and now let's switch back to the slides
and move on so with all this talk about
packages you might be wondering how the
system actually knows the difference
between a regular directory and a
package and there's actually three
things that can turn a directory into a
package and that was kind of necessary
for historical reasons I guess for some
existing packages we had the first one
is that we actually defined an HFS
catalog info bit that was unused for
directories and we call it the package
bit if you need to know it's bit 13 its
it corresponds actually to the bundle
bid for files but for direct for
directories it was unused I'm told that
in the original Mac OS planning back in
1984 they wanted to do something like
this and it only took us what 16 years
17 years so there's a there's a bit and
when you set that bit magically the
directory gets presented as a package
now that's actually not quite enough
information because since directories
don't have don't have types and creators
we don't we don't really know anything
about that
so it's always good to have a package
info file there whether or not you use
the package bit but it turns out if you
if your directory has some sort of valid
extension and a package info file in the
contents folder that's enough to tell us
that it's actually a package in one
other way is and this is documents as
packages if the directory has an
extension on it and that extension is is
claimed by some application has a
packaged
then we'll know from our bindings
database that this directory needs to be
presented as a package but typically
application packages you want to have
the package info file so that we know
that it's an application so the rest of
the time on packages I want to talk
about the property lists because this is
really how you communicate to your
application what your application or to
the system what your application can do
the property list tells us things like
what the name of your executable is so
we can launch you what version it is
what types of documents you can open in
something we've added is what kind of
you our URL schemes you can handle so if
you are an FTP client you can handle FTP
URLs or a browser or even if you have
your own private schemes you can specify
them here and that allows the system to
route a URL with your scheme to your to
your application again the property list
is something that all bundles have it's
it's an in fact korfin the core
foundation bundle api is is what you use
to manipulate bundles in and all of the
keys that I'm gonna go over soon
start with CF bundle because this is all
defined by core foundation in general
the property list has a lot of parallels
with the single file application model
universe resource B ndls F ref open
resources and kind resources all this
information is now in the property list
as well as additional things that were
adding over time the property list
itself is actually just a text file it's
an XML file which means that
corefoundation can easily read it in as
a property list it's implemented as a
dictionary which means it's easy to
extend we just add new keys and when you
ask for a value of a key
corefoundation D references or it looks
up the key gives you gives you back the
value we defined we've defined a number
of standard keys and these are the
things that the system looks for when
scanning over your application package
as I said before some of the values
should be localized I'm going to keep
saying this because I just want to keep
reminding you if you don't localize say
you're you're kind strings in the right
place then
they won't be it won't be ready in the
finder for users to see your kind
strings now what if you're actually not
quite ready for packages but you really
want to have a property list and this is
this is important because in fact if you
really want to get nice big aqua icons
associated with your documents you need
a property list or if you really want to
make sure that you're able to claim
certain extensions file extensions then
you need a property list so we've made
it possible for single file applications
to also have a proper list in fact if
you if you do this then it's one way we
know that you are actually a native
application and not a classic
application what you do is you create a
PL ST resource with ID 0 add it to your
application and simply paste the
contents of your of your xml property
list into the resource the only thing
that has to change is that in the places
where you're specifying an icon and
instead of specifying a file name for
the icon you actually are specifying a
resource ID so it's just a number and we
then we looked for an icns resource with
that ID in your application
ok now let's keep moving here these are
not all of the keys that you might see
in a property list but these are the
essential ones and I wanted to zip
through each one CF bundle names it's a
name for your bundle it ends up being a
user visible name so this is something
that you want to make sure you localize
in your strings file where it's visible
right now is say in the menu bar the
application menu is actually that text
comes out of your property list
something that's not user visible is the
CF bundle identifier it's designed to be
a unique identifier so we used the form
of a like this in the style of a Java
package name kind of a reversed domain
name and this gives us a name nice name
spacing and allows the system to count
on using this as a unique identifier for
your application your bundle in addition
to the package info file we also want
the Taiping creator to be in the
property list so the package type for
applications it's always going to be a
ppl
and then of course the the signature is
the same as the creator and that's your
four four character OS type that still
should be registered with apples so that
we're sure dove some level of uniqueness
for creator types our creator signatures
I should say the version this is
important for differential helping the
system differentiate between different
versions of your application that
sometimes comes up in launch binding or
document binding and the icon file this
tells us what icon to actually associate
with your application package in the
finder or in the file dialogs and then
finally the executable name which is the
file down in the Mac OS directory now
there's two others that are a little
more complicated and so I have to drill
down into these the document types and
the URL types these are how you
associate documents on the system and
URL schemes with your application it
tells it lets us know that you can your
application can handle various types of
documents and URLs and those keys are
actually arrays and each value in the
array is a nested dictionary again so
it's all very extensible so for each
document type that you can handle we
have a number of keys and I'm not going
to go through the URL keys because
they're very similar and I want to
really focus on document binding today
the first one is the an abstract name
for the for the type and this ends up
being user visible this is actually the
kind string so you want to make sure
that this key gets localized in your
strings file moving on the the icon file
this tells us what icon we go and look
for this resource and your for this file
in your resources directory and
associate the icon in there with
documents of this type in the finder the
next one is a new concept the role we're
introducing an understanding of roles in
Mac OS 10 and this is a way to give us a
little more information about what your
application can do with documents of
this type
and the only two we have defined right
now our editor and viewer so full-blown
acrobat is an editor of PDFs that
acrobat reader is a viewer of pdfs and
that's about as clear a definition as
you're going to get of the difference
between editor and viewer it's not
always so clear but we think it's a
pretty useful distinction in a lot of
cases this this actually is a required
key you got to tell us your one or the
other and it comes into play when we're
doing document binding and then for each
abstract type you can actually associate
a number of OS types that is type
signatures as well as extensions with a
given abstract type in the case of OS
types the reason you might want to have
several instead of just one is suppose
you Reb your application and change the
file format so you want to change the OS
type for your document well those are
really kind of the same abstract type
for the for the most up-to-date version
of your application you can handle all
of those types you would list them here
in the array and similarly with
extensions you might have extensions
that have changed over time or you might
have different versions of really the
same extension such as HTML and HTM you
want to treat those as really the same
abstract file type so you can list them
all in this array of type extensions and
let's see I guess I have a demo here
what do I need to do
right so here is the property list and I
was just going to open it up in BB edit
and do this BB edit does some nice
coloring so as you can see it's an XML
file here are the tags like here this
says that this particular XML file is a
dictionary like I said and there's a
number of keys some of which I've talked
about all the CF bundle types there's an
array of types and each each item is a
dictionary like I said if we look down
here some of the other keys I talked
about the executable name is sketch the
icon file is actually draw to app and
obviously this is not the best user
interface for dealing with property
lists and so if I actually go out here
and double click this it will open in a
little tool a developer tool called
property list editor that gives you a
much nicer interface for creating
property lists you can see you can
pretty up progressively disclose the
property list to see all the keys we've
been talking about see all the document
types this is an array there's several
types that are that are supported by
sketch so this is a nice tool for
actually creating a property list but in
addition to that both project builder
and code warrior' provide assistance in
building your property list down inside
the resources directory again is where
the the localized part of the property
list is and if you're looking here and
you by all the disclaimers
what's in the strings file is the same
keys for instance the bundle name and
then the localized value of it is sketch
in English okay end of demo
so that is not all the details about
application packages but the massive we
really want you to hear is that there a
new option that has great advantages
over the single file application
structure it gives a nice simple
presentation to the user with a with a
lot going on inside because it contained
milk contains multiple localizations
your application is actually globalized
you take a single image of your
application and it can run in many
different languages not all at the same
time but it changes as needed and
because of the way the definition of a
package is set up in a bundle it's very
extensible for the future the key to
getting a great user experience with for
your application package on 10 is
getting your property list right and the
best way to do that is go out and read
the documentation we have there's
various tech notes on this subject and
also look at the sample code the sample
apps try to do a good job of having
their property lists just the way we
want them to be and that brings us to
the second half document binding so it's
great the system knows all about your
application now if you have a property
list we look at that if you have a P
list resource we look at that or if
you're a single file application and you
have a B NDL and f4f resources and kind
resources we still look at that and we
have all this information about what
your application can do document binding
is what makes this work it's the service
that associates on-the-fly documents in
the file system with the applications
that can handle them it's what makes
double-click work in the finder and as a
general term I'm using it to refer to
the new capability of binding URL
schemes to applications as well so
in order to understand what's changing I
want to look at how things used to be
in 1984 the Mac was introduced and we
had totally freeform filenames and we
introduced type and creator in order to
free the user from having to worry about
metadata and and and how documents could
associated with applications and that
worked great because there wasn't a
whole lot of file exchange going on
every Macintosh was kind of an island
and the file exchange that was happening
tended to be between Macs if we fast
forward to today the picture is a lot
more complicated the world is a lot more
interconnected and it's not so simple
anymore
so for instance we've got files that
come onto the system say from outside
sources through an email program for
instance and all we know about the file
maybe is its file name and it's bits so
in that case we can look at the file
name and say mmm well it has an
extension and that doesn't do as much
good on the Mac so the email client is
the gatekeeper and it's responsible for
figuring out what is that extension map
- yeah because if I don't that email
program doesn't set the extension I'm
sorry it doesn't set the type and
creator then it's not going to be very
much use to a Mac user and so the
gatekeeper takes care of that transition
similarly files going out if letter to
mom doesn't have an extension on it it
might be going to a Windows user and the
file is not going to be much help to a
Windows user who doesn't know how to
open it because it doesn't have an
extension on it so the gatekeeper again
is responsible for doing the transition
you might say are you sure you want to
do this do you want to add an extension
to this file in fact that happens
sometimes but not very reliably another
problem with the gatekeeper theory is
that you can always tell actually when
you're crossing the boundary maybe
you're putting a file onto a disk
might be a file server or a removable
disk you know it looks like an HFS disk
maybe it's an AFP server you don't want
to force extensions in all cases there
but the fact is if the file doesn't have
an extension and the disk is accessed by
a Windows user or another operating
system it probably isn't gonna need an
extension or to be understood but you
can't tell that it's actually gone
through a gateway and just to add one
more thing to the mix Macintosh is
working as web servers are hosting a lot
of files and have extensions on them and
so right on the system you've got files
with extensions on them and yet the
system still knows very little about
extensions so the gatekeeper theory kind
of breaks down in this very
interconnected world and we're left with
a lot of file exchange going on and not
always a good user experience because
document binding doesn't always work so
what's the answer well if this was an
episode of Star Trek Voyager I would say
we could just assimilate Microsoft and
we could banish extensions from the
universe and make sure that everyone
who's using types and creators listen I
don't know what the Linux people would
have to say about that that would be
nice huh
problem is we're the good guys right
that violates the prime directive we
can't do that so the next thing that
happens whenever you're doing battle
against the Borg anyway is you
remodulate your shields
there's two problems with that first of
all it never works for very long the
board see right through that right the
other problem is it has nothing at all
to do with document binding so we can't
do that however it occurred to me that
what we are doing is something that
Captain Janeway does all the time she
takes an alien technology and uses it to
her advantage and that's what we're
doing by recognizing extensions on Mac
os10 extensions are out there they're on
Mac systems they're coming in all the
time and the fact that we don't
recognize them at all is just getting in
users way in the way of users and so I
picked this word recognized very
carefully because we're not trying to
get rid of anything else we're just
saying that extensions are an
interesting piece of metadata it tells
us something about a file and we want to
provide the best possible user
experience for our users a lot of users
are interacting with extensions by
necessity and the way to help them is to
recognize them as a part of the system
so what comes from that decision well
the goal of document binding remains and
always will remain that we want to
always launch the right application when
opening a document the right application
of course is what the user wants so we
have to do some mind-reading if we could
read the users mind that would be great
document binding would just work our
goal is to approximate mine during as
much as possible and in order to do that
we want to recognize all available type
information type creator extension
whatever might become available in the
future in addition we want to give the
user a little bit more control actually
of how binding works so that they don't
just have one choice for binding that
they can do some overriding if they want
now the user experience we have in Mac
OS 10 is not completely done
extensions are fairly new to the system
and we're on our way to something that
we think is a great user experience and
I'm just mentioning this because I don't
want to want you to think that what we
have in Mac OS 10 we think is perfect
it's not perfect but we do think it's an
improvement especially for users that
need to work with extensions a lot so
first of all what is an extension well
we've tried to give a fairly constrained
definition for an extension because
we're adding it onto a system that
already has a bunch of files on it
some of those files might have
extensions other files might have things
that look like extensions but are just
we're just put there by the user and
aren't really extensions something like
oh I don't know but by constraining the
definition of an extension we are
reducing the number of false positives
on finding an extension so the extension
is all the characters following the last
dot the character set is a through Z 0
to 9 dollar sign percent underscore and
tilde notice there's no spaces allowed
in extensions and there's one more
restriction if although digits are
allowed numerix are allowed if the
extension is all numbers then it's not
seen as a valid extension so it's
ignored as an extension by the system so
what are some examples of this well
first to our similar document names
search they both have a surf paint
extension with slightly different
capitalization those are actually
recognized as the same extension
extensions are always matched
case-insensitive so those are the exact
same extension ListView see of course on
the last one in mp3 file that has digit
in it but it also has letters so it's a
valid extension oops
the invalid ones surf paint surf paint 1
0 that's just a number so it's not a
valid extension surf paint 1.0 v2 has a
space in it
we disqualify that and if somebody left
to put dates at the end of their file
name
and it ends in dot zero one that's not a
valid extension either so those things
are right out we don't recognize as that
as extension metadata so given all of
that how do we actually bind documents
in Mac OS 10 well the first thing is
that users can for specific documents
say exactly which application they want
to open when they double-click this
document so in the info window of the
finder there's actually a panel that
allows the user to say for this one
document I always want to open it in
this application over here and that is
the first rule and the overriding rule
that if the user has set that that's the
application they're going to get now if
that's not set which it would would
generally be the exception because
that's an advanced feature not something
we're obviously we don't want to require
users to do that the next thing we look
at is the creator we look at the creator
and we say do we have an application
with this creator on the system and if
we have more than one we have to do some
best matching which I'll get into but
the important thing is if the Creator is
there and we can match it then that's
how we're going to bind the document I
want to point out this is how it works
on Mac OS 9
this covers 99% of what happens on Mac
OS 9 so right here you're getting
behavior that is pretty much in line
with what happens on Mac OS 9 the next
thing we're going to look at is the
extension if there is one if there's an
extension we want to consider it first
because there's some important cases
when the extension actually has more
meaning in it than the OS type and a
great example is text files they're all
T ext on the Mac and that's why you see
text files with extensions on them so
that the system can tell the difference
now actually the Mac OS 9 system can't
tell the difference very well but on 10
we can look and say oh it's an HTML file
doesn't have a creator or the creators
missing but we're gonna launch it an
internet explorer or it's a dot C file
we're gonna launch it in code warrior
and then we look at the OS type but we
don't find an extension match or there
is no extension then we look at the type
and we try to find an application that
can open that type of document in all
these cases there might be some ties so
let's look at how we break ties for
creator binding well let's say we find
more than one app with the same creator
in general it's going to be a different
version of the same app and we break
ties in that case by always launching a
native app over a classic app if there
are two native apps for example then
we'll look at the version numbers in the
bundle or the verse resource and then
finally if that fails then we'll try to
break the tie by the latest modification
date and if that fails then we have the
same app and it doesn't really matter if
we have to drop down to looking at the
type in order to achieve the binding
then we look again at a user preference
this is an advanced feature but most so
most users won't be doing this but it
hits the spot when you need it and that
is you can say the user can say that
HTML files I always want to open them in
Explorer for any particular type you can
the user can specify their preference if
that's not set then we have some other
rules and this is where the roles come
in if we have an editor and a viewer to
choose from then we'll pick the editor
and by the way unless classic apps
indicate otherwise through a property
list all classic apps our viewers
considered viewers and so this this will
also give an edge to native apps but
finally if all things are equal then
we'll still pick a native app over a
classic app so that is in a nutshell the
binding rules there are some nooks and
crannies that I didn't get into but
that's that's the essential expression
of what happens so given all of this
what are the guidelines for creating new
documents on Mac OS 10 well
you want to maintain binding for
everybody
ideally and so this actually came up on
the discussion list recently Apple a
chai dev and a pretty good way to put it
is save all the metadata that you have
so if you're an editor for a type of
document the user is saving that
document it totally makes sense you're
the creator for that document you should
set the type and creator for the file
and if your users might possibly be
interested in opening that file on
another OS then the best policy is to
also have an extension for that document
you might not want to force that but a
number of large applications already do
and not just Microsoft applications I
might add it's something that our users
need in some cases and so having all the
metadata there enables us to do the best
possible binding and for binding to work
on all operating systems however there
are cases when you're actually
manufacturing or deriving that a data
and that might not actually make sense
to save metadata that you have to derive
so for instance if the file is incoming
over the network as an and is excuse me
as an attachment you might just have an
extension and you can ask internet
config for you know we can do the
gatekeeper thing and say what's the type
and creator for this well the fact is
what you're doing when you ask that
question is internet config is
consulting the launc binding or the the
document bindings database and it's
giving you back the same information
essentially that you get when the
document is double clicked in the finder
with just an extension so by in other
words by saving the type and creator at
that moment you're kind of freezing the
binding for that file at that moment
when in fact all of that happens
dynamically now in the finder if there
is just an extension your file will bind
just fine so there's no need to derive
new metadata
other interesting things that you should
do when you create a new file the users
like to see their files show up
immediately they'd like to see it in the
finder you know they know that their
data is all nice and safe on disk and
the finder does not poll periodically
that's a big performance problem if you
do that and so on the chance that your
file is visible in the finder or should
be visible in the finder after you save
a new file or after you remove a file
for that matter if you do you can call
this new function on Mac os10
FN notify passing in an FS ref to the
directory that the file is in and that
will wake up the finder and maybe some
other clients for the notifications and
the finder will redraw its window and
the file will appear and the user will
see it even with the window in the
background by the way the save panels in
both carbon and cocoa will do this for
you so you don't you don't have to do it
if you've gone through a safe panel to
create a new file wild card document
types well it used to be in a single
file application you could claim four
stars
and get wildcard binding for drag and
drop purposes and you can still do that
in your property list if you claim four
stars you're saying that you can open
any file at all any file can be dropped
on your application we've added one new
one which is claiming an extension of
star just one star and what that does is
it's a little bit different it says you
can open any file that has an extension
and that's that's somewhat useful
because you're saying that you open any
file that has an extension and that
you're going to look at that extension
to figure out what the file is that's
why it needs to have one both of those
can appear in your property list and
finally the one last thing I really want
to go through in this talk is how to
open a document and the launch services
API in general this is a new API
available only on Mac OS 10 it is the
engine that does document binding it
opens documents that opens URLs and it
also provides some API for getting all
sorts of information so if you have a
file or a folder or an application
you you have some questions about then
use launch services to get that
information and let me go through real
quick how it works as I said it's only
available on Mac OS 10 it maintains the
bindings database it does also save
relevant information back to the desktop
database so that if your user does boot
back into 9 anything that got installed
while 10 was running is in the desktop
database to the fidelity that the
desktop database can handle and finally
Oh however I should say don't rely on
the desktop database for getting binding
to work on 10 in fact there is one more
step in document binding which is a
last-ditch effort to buying things if
all else fails we will go back and
consult the desktop database to see if
we can find some application to open a
document but it's really the last resort
and if you want to work well on Mac OS
10 you want to make sure that your
application goes into the launch
services bindings database launch
services is used extensively by the
finder it's essentially code that used
to be in the finder that did all the
bindings what we've done is we've made
an API public so that you too can be
like the finder if you want you to open
things you want things to open in the
same exact application that would happen
if the user double clicked something in
the finder use launch services so what
can you do with it well you can open
documents and URLs there's two ways the
easy way which is takes an FS ref or a
URL and what that does is the easy way
is essentially the same as
double-clicking there's no options you
just say take this thing and do the
right thing with it and it's the same as
what the user is asking for when an item
gets double clicked if it's a URL we
look at the scheme we find out what the
best application is to open that
particular kind of URL we launch the
application and send it the URL Apple
event if you need more control than that
then there's API available that allows
you to do things such as
launched more than one documented tongue
I have an array of documents I want to
open them all and by the way I also want
to open them in a specific application
not the default application but I know
the application I want so I'm going to
specify that and there's some other
options such as passing Apple event
parameters to the application when it
gets launched some pass through params
all of these things by the way are in
launch services H and on Mac OS 10 and
there's some extensive header
documentation in there that will help
you figure out exactly what each part of
the part of the API does there's also a
tech note on this which will give a URL
to at the end the rest of the launch
services API is all informational it
allows you to answer questions that you
have about various things so for
instance LS copy item info for F or for
URL this allows you to pass in options
essentially ask them questions saying is
this item a package is it a volume is
that an application you know I have an F
I have an FS rough I need to know
something about it if it is an
application is it classic or a native
app does it have an extension and what
is the extension don't rely on just
looking for the last dot and a file name
as I said there are rules about what's a
valid extension launch services defines
those rules by providing the API to get
it the extension getting bindings
information if you want to find out what
the binding is for a document without
actually opening it or for a URL you can
call this get application for item or
for URL and it will actually return to
you a an F s ref or a CF URL to the
application that is the default binding
for that item if you don't have an item
but you have some metadata a creator a
type or an extension or maybe all three
or some combination you can passing
whatever you have to get application for
in
and it will return to you the best
possible the best match for binding that
metadata and finally this kind of an out
ball that if you have something else to
identify an application such as an
application name or just a creator or a
bundle identifier like comma l-dots
catch this API we'll go and find search
the bindings database for that
application in that that might be
something special
especially with bundle identifier might
be something you need to do drag and
drop again the finder uses this in order
to figure out drag and drop acceptance
so you can - you've got two items you
want to know if one can be dropped on
the other you call LS can ruff accept
item or can URL except URL if you're
dragging around a URL kind strings you
need to know the kind string for a
document this is this API returns for a
document or even for a URL the kind
string pulled out of the bound
application so it does the default
binding and it goes and looks in the
package looks in the property list and
finds the localized kind string for the
document returns it to you as a CF
string and finally these functions are
completely useless
Ellison net and LS term actually are
unnecessary you can call them it's
harmless but we decided to make it
happen implicitly when you call any of
the LS functions and so you'll see that
there's like some options for LS and net
which might become useful in the future
but for today you don't need to call
them don't worry about it ignore them
until we tell you otherwise all right
how do you make sure that you're in the
bindings database it's kind of
embarrassing if you install your
application and then your user can't get
it to launch by double-clicking a
document well today the finder is solely
responsible for updating the bindings
database and it does some things
automatically for you if
whenever the user logs in the finder
looks in some well-known places such as
the main Applications folder for the
system the users application folder if
there is one some other places I think
like scripting editions and it notices
if anything has been added or removed in
those places and it scans the subfolders
as well not just not just the flat
folders and it makes sure that all the
applications in those locations are in
the bindings database whenever an
application is launched by the user so
you know right in the finder you double
click on an application or you double
click on one of its documents the finder
will make sure that that application is
in the dining database obviously if you
double click on one of the documents it
must already be in there but if you
launch the application it will get added
to the bindings database but you also
need a way to install your application
and make sure it gets added to the
database and the way you do that today
is you need to tell the finder about it
and the way you do that is with an
existing Apple event protocol called the
sync Apple event or KAG sync this
constant I think it's in finder registry
dot H and what you do is you create one
of these sync Apple events you add you
make an alias to your application not to
its curtain to them not to the directory
it's in but the application itself the
package or the binary you add that alias
to the sync Apple event and you send it
off to the finder and that wakes up the
finder the finder adds the application
to the bindings database so if you're
installing well what are your choices
first thing you could do is just rely on
packages for a nice drag-and-drop
install experience you have a CD put
your application on it the user pops in
your CD drags the application package
over all the goo is hidden inside the
package they drag it over they
double-click your document sorry he
double-click your application and boom
he gets it gets added to their bindings
database but certainly they're going to
be cases when you need to do something a
little more formal than that so if
you're installing multiple applications
or something run through your installer
but don't force a restart or a logout
you might want to think you can fourth
you know make the user logout they'll
log back in the finder will scan and
find your application but there's a much
nicer way to do it and that is with the
sync event so copy over the application
send the sync event everything goes into
the bindings database if you have more
than one application obviously send one
for event one event for each application
so in summary for document binding our
goal remains and always will remain to
read the users mind to make document
binding work intuitively in order to
achieve that we've added a new type of
metadata to our bindings information
that we consider the extension so that
all available type information is
recognized by the system and this should
result in ultimately a better binding
experience for the user
we've also added the ability for the
user to exert some control for advanced
users over specific binding of specific
documents and in general the best
practice for you in creating new
documents when you're the editor of the
application ethically when you are an
editor application is save all the
metadata you have type and creator if
your user wants to work with extensions
save an extension also that will ensure
that your document can be correctly
bound everywhere and finally the launch
services API is really your access to
all of this gives you all sorts of
information about bindings and it's
exactly what the finder does and so it's
a great way to make the finder so
there's some relevant sessions here
localization is on Thursday designing
icons is on Friday
corefoundation in the bundle API for
accessing bundle contents on Friday a
couple of project builder sessions
unfortunately were yesterday and today
and finally if you want to learn more
about shield remodulating be sure to
catch Star Trek voyagers final episode
right here tonight at 8:30
you