Configure player

Close

WWDC Index does not host video files

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

URL pattern

preview

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

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

WWDC06 • Session 107

Software Installation Strategies

Application Technologies • 53:25

Distributing, installing, and configuring software should be easy for developers and users alike. Learn how to get the most out of the Mac OS X Installer by exploring basic, intermediate, and advanced software installation scenarios. You'll learn key features of PackageMaker, when to use Internet-Enabled Disk Images, how to locate and upgrade your application on any system, and much more.

Speakers: Peter Bierman, Sean Kelly

Unlisted on Apple Developer site

Transcript

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

I'm Peter Bierman. I work on the Installation and Setup group. I'm going to be talking to you today about software installation strategies. Now, I'm going to mostly be covering Mac OS X, 10.4, Tiger, because all of you are hoping to ship your application soon. I'm going to be covering creating PackageMaker, creating packages with a new tool we've got, PackageMaker 3.0. It's brand new, coming out in Leopard. We're hoping to have it also run on Tiger.

I'm going to cover various ways to deliver your software to your customers, things the installer can do. I'm going to go over a bunch of installer features, some of the more confusing things that people have asked us questions about. And to do this, I'm going to break down the topic into four major sections. I'm going to talk about creating your software, creating your packages, delivering those packages, installing the packages, and upgrading. So let's talk first about creating packages.

First, the reason you create packages is to walk the user through the install process. A lot of users are somewhat intimidated by installing software, by modifying their machine, and an installer package gives you the opportunity to present this task in an easy, hand-holding kind of method, where the user sees each step, they expect what's happening, they know what to do next.

The installer also has a bunch of features related to some of the more advanced techniques getting software onto the user's machine. For example, the installer can allow the user to authenticate as an administrator, and you can install files as root, which the user wouldn't normally be able to do.

The installer also has the ability to find relocated files if the user drags their application somewhere else after they've installed it. The next version of your installer can find that, install it where they chose to put it, and there's a bunch of other features. So, to create packages, the first step is you need to get organized.

You need to know what you want to present to the user. You need to know what software you're actually going to put on the user's machine and make sure that it is what you want to put on the user's machine. Every file is where it's supposed to be. Every permission is set the right way.

So, you want to check those things out before you create your packages. And finally, you want to take note of any special requirements your software has, things that you're going to check for the user before they install and inform them, hey, you actually need an iSight camera to install this or it's not going to be very useful, things like that.

So the first step is to use PackageMaker. Now, in Leopard, I mentioned earlier, we're introducing new PackageMaker 3.0. It's great. It's vastly improved over the previous versions of PackageMaker. Earlier versions of PackageMaker were more like a property list editor. They exposed all the features of the installer in terms of checkboxes and pop-ups, but it didn't really put it together in terms of what you were trying to accomplish. The new version of PackageMaker is much more workflow oriented. It lets you start with your software, give it to PackageMaker, and PackageMaker gives you packages.

So to see that, we're going to start out with a demonstration. I'd like to introduce Sean Kelly. He's the engineer that's been working on PackageMaker so hard for the last year or so. And Sean, let's see it. Thank you, Peter. Could we switch to the demo machine? Good morning, everybody. My name is Sean Kelly. I work on PackageMaker at Apple. In today's demo, we'll create an installer for three items, two applications, and a widget, along with some interface resources. So let's get started.

As Peter suggested, I've gathered the items for my installation, the two applications, and the widget, along with my interface resources. So, we'll launch the new PackageMaker 3.0, a new document will be created, and the Install Properties dialog will appear. This dialog drives much of PackageMaker's behavior. The Organization field is used to pre-populate your package identifiers, while the Target determines what PackageMaker will build. If you target Leopard, you'll get the new Flat packages, while if you target Tiger or Panther, you'll get the old Bundle packages or Meta packages. So today, we'll build the WWDC Demo Installer. It's from Apple, and we'll target Tiger.

This item up in the upper left corner, which says WWDC Demo, represents your installation as a whole. So metadata, such as your title and your description, if you need to set requirements, you can do that here as well. To add items into PackageMaker, you can just drag them into the Contents area. We'll see that PackageMaker has figured out that Sketch is an application, and it's filled in some default information for you, such as an install location. It's pulled the version number out of the bundle. It's given you a package identifier, a recommended authorization level. It's made it relocatable.

If we go into the Contents tab, PackageMaker will pull up the contents of your package, and you'll be able to edit the ownership and permissions. It's very important that these be correct and be how you want them to be on your user system when you install. Fortunately, PackageMaker makes this easy for you.

If you use the Apply Recommendations button, PackageMaker will scan the contents of your package and your install location, and apply the ownership and permissions that meet our best practices guidelines. Now, before we add the other content items, I want to show you one of the features of PackageMaker.

Instead of you having to decide if you want a package, a meta package, or a distribution, PackageMaker will figure that out for you based on your configuration. In Leopard, we've introduced a new feature called Install Domains, which allow you to install in the user's directory or on the system. Now, this only works in distributions. So if you turn any of these domains on, you'll see that PackageMaker has changed your installation into a distribution.

So now we'll add our other content items, and again, we can just drag them in. And we'll see that PackageMaker has figured out some default information for the widget as well. Now, of course, you can change any of this to however you want. If you make any settings that PackageMaker thinks will cause problems, it will give you a warning during the build.

So now we'll set our interface resources. We'll go into the properties of the install as a whole, and we'll use the Edit Interface button, which will bring up the Interface Editor, which is what you see is what you get interface. What you configure here is exactly what the user will see during their installation.

So to add your resources, you choose which one you want from the list on the left, and then you drag your files into PackageMaker. So today we have a welcome or an introduction. We have a read me. and we have a license. So if we build our package, we'll save it onto the desktop.

And we'll open it in the installer. And we see we have our interface resources, our welcome, our readme, our license, which the user has to agree to. And if we continue through the installation, our applications will be installed into /applications and the widget into library widgets. So before I turn it back to Peter, I want to show you one more feature that we've introduced in PackageMaker. We've added an extensive verification process into the build.

So to show you that, I'll open a document that I've created for the installation that we just walked through, except that I've seeded it with some errors. So if we build this... We'll see that PackageMaker comes up with some errors and warnings. If we expand one of these, we'll see what the errors are, and we'll also see these magnification buttons. If we click one of those, PackageMaker will change back to the main interface, and it'll spotlight the exact item in the interface where you need to make your changes.

You can then bring up the Build Results window from the Project menu, and you get the same interface. And you can click through all of your errors, and then just click through in the interface and make your changes. So that's a brief introduction to PackageMaker 3.0, and I'm going to turn it back to Peter.

Thanks, Sean. That's a vast improvement over earlier versions of PackageMaker, and I think you can see that our investment in PackageMaker over the last few years is really paying off. We're committed to continuing to improve PackageMaker to support features as we add them to the installer and make it easier for you to make packages using our tools. So that's creating packages. Let's talk now about delivering packages.

Now, packages in Mac OS X are bundles. That means they're directories with other directories and files inside them. And that means that generally when you distribute them to your customers over the Internet or via email, you have to wrap them in another container like a zip file or a disk image. Also, in Leopard, in 10.5, we're going to be introducing a solution to this that doesn't involve containers, flat packages, and I'll talk a little bit about that.

First, zip files. Now, zip files are really easy to understand. You just go to the Finder, click on an object in the Finder, select it, Control-click or right-click if you have a two-button mouse, and you see the Create Archive command there in the Finder's contextual menu. The Finder will create you a zip archive of whatever you have selected. Now, the zip archive, when the user double-clicks it, it'll just expand back into whatever it was before.

So, there's no opportunity for you to add additional user interface explaining to the user what they're supposed to do next. There's no way for you to add a license agreement, any other sorts of instructions. It's just what you see is what you get. One file, multi-files in, one file out.

Next step up from that is to use a Disk Image. Now, Disk Images are the recommended way of delivering your software's simple applications to customers, as we currently document them. Disk Images support a lot of file system features, because they are, in a simple sense, a file system. They handle resource forks, for example, but not special authorization. They won't ask the user to authenticate as an admin so that they can install things as root.

But Disk Images do support a few installer-related features, like the ability to display a license agreement or have a background image, which you can use to kind of inform the user, "Hey, you should probably do this." A good example of that, here we see a screenshot of the Firefox Disk Image, and on the left side of that you see the Firefox application. And in the background, there's a background picture that's meant to imply to the user that they're supposed to drag Firefox into their applications folder.

Now, all of you probably understand that. I would wonder how many of our users understand that. So this may confuse novice users, but it is a pretty good user experience in terms of the user can control what's installed and where it's installed. To find out more about Disk Images, you can look at the Disk Images man page, which is HDI util.

Now, there are improved Disk Images. These are called Internet-enabled Disk Images. And these will automatically, when downloaded by Safari, mount themselves, extract their content, unmount themselves, and move the Disk Image file to the trash. If the contents are an individual installer package, that will be opened in the installer, and the user will go straight from clicking on a link in their web page to being in the installer. That's an improvement.

And it's such an improvement that we'd like to support that directly in Leopard without having to use Disk Images at all. But until then, to see how to do this, you can look again at the HDI util man page, and the command itself is HDI util Internet-enabled, and then your Disk Image.

So those two things sort of reveal one of the flaws in the installer, one of the areas where it doesn't quite allow the seamless integration between the web and installing software. And so to rectify that, in Leopard, in 10.5, we're introducing flat packages. Now, flat packages are just like our regular packages. They have the same file name extension, .pkg, .mpkg, but they are an individual file. They're not a directory. The file format is ZAR.

This is an open source project that's been worked on by a bunch of former and current Apple employees, and it's not limited to the Macintosh. The goal, actually, of the ZAR project is to support creating archives that support all of the extended file system attributes of all of the various operating systems that are out there.

In particular, it makes a good mesh for what we want to do with the installer, so we use the file directly. The single flat file can contain one or many packages, and this enables a feature that we'll talk, we'll cover in even more detail, in our other session on Thursday afternoon called Quick Start Installs.

So that's delivering packages to your customers. Let's talk about what happens when the user gets your package and now goes to install it. So what can the installer do? Well, some of the most significant features of the installer are these. The installer can find relocatable software. The installer can enforce requirements. The installer can allow customization. The user can pick some parts of your software, but not others. And the installer also supports custom plugins that you can create and give the installer a unique user experience.

So, relocatable software, what do I mean by that? Well, on a Macintosh, applications don't have any particular need to run from any particular location. Most users are used to seeing all of their applications in the Applications folder, but there's also the Applications Utilities folder, and you might have noticed that a lot of Apple's applications actually run out of a Core Services folder somewhere else.

So, that's how we ship the OS. Users are free to configure their Applications folder however they'd like. Maybe they want an Internet Utilities folder, maybe they have a Graphic Utilities folder, maybe they just have a big mess on their desktop. Whatever they have, this is the Macintosh ease of use.

The user is in charge of their machine, they can do what they want with their machine. And so, it's important for you to support this ability. Now, to do that, in the past, it's been very difficult. It's involved writing what's called a Token Definitions PList. Now, it's just PackageMaker. It's just a checkbox. You don't have to do hardly anything else.

So the next feature of the installer that people frequently encounter are requirements. Requirements are merely the way for the installer to tell the user, hey, you're not actually ready for this software. You need more hard drive space. I mean, there's enough hard drive space to install the software, but then it's going to go and create 5 gigabytes of images, and so you probably want to have space beforehand.

So you can check for supported hardware. Does your application need an iSight video camera? You can check for which volume the user's going to install your software on. Maybe the user is going to install your app on their other operating system that's on a different volume. Here you see a bunch of volumes, and none of them are allowed. They all have a little stop sign.

Now there's also the Custom Install Panel in the installer, and this is an opportunity for you to provide optional content for the user to install. You may have noticed Leopard and Tiger and all of the OS releases before it have a fairly extensive Custom Install Panel, where, for example, you may choose not to install every font that we provide or all three gigabytes of printer drivers.

Using the Custom Install Panel, you can give the user these choices, and they can choose not to install them, or you can also set up what the defaults are, and you can dynamically control those defaults based on the hardware that the user is actually installing on or other software that's installed. So you have control over the enabled, selected, and visible state of every item in that Custom Install Panel.

Finally, another major feature that the installer, we've been asked about a lot, are installer plugins. Now, installer plugins are the ability for you to insert your own panel into the flow of panes in the installer. You can, for example, ask for a serial number or registration information. But the key to remember when dealing with plugins is that the user can bypass them. The user doesn't have to use a package to install your software. They can take the package apart themselves and get the software that way. They could have gotten it from a server somewhere.

Or maybe there's a system administrator that's trying to install your software on a thousand machines at once, and they really don't want to have to go through the installer and type in a serial number into each panel. So it's important that you don't depend on your installer plugin as a critical part of installing your software. It's merely an opportunity for the user to perform some task when they're in the mindset of installing. So how do you use these features? I'm going to go into a little bit of detail here. First, we're going to talk about enforcing requirements.

So requirements themselves are generally written as little snippets of JavaScript that live inside the distribution script, which is an XML file inside your package. Now, this is all 10.4 Tiger technology. Last year, we were talking about it, I think, for the first or maybe the second time, and it was brand new, and we were encouraging people to use it. Now it's here. Most of our customers have Tiger. This is something you can depend on. The advantage of writing your requirement checks in JavaScript is that you're not running an arbitrary executable as soon as the user double-clicks on your package.

If you don't use the JavaScript ability to write requirements, the user's going to see a little warning sheet that says, Hey, this package might be dangerous, and you don't want that. So these requirements, they have access to system configuration information through our JavaScript APIs, and they can block or warn for the whole install or specific volumes.

These two requirement checks are generally called the installation check and the volume check. The installation check, like I said, warns for the entire install. The volume check checks for volumes. PackageMaker gets you started writing requirement checks. PackageMaker 3.0 has a fairly simple requirements editor. It lets you select from a fairly extensive list of example requirements.

Does this machine have a certain amount of RAM? Does this machine have a certain amount of hard drive space? Does this machine have a certain node in the I/O registry? But generally, when you write a requirement, you're going to reuse it elsewhere in your package. You're going to have both a volume check, and you might have something in the custom install panel. And so for these more complicated interactions, you're going to go directly to the distribution script, which is inside the package.

So to demonstrate that, both the requirement editing ability in PackageMaker and how to get directly to the distribution script, I'm going to go back to Sean. Sean? Thank you, Peter. Could we switch to the demo machine, please? So in this demo, we'll add some simple requirements to a Sketch package using PackageMaker, and then we'll dig inside the package and show you how to modify those requirements by hand. So I have a PackageMaker document that I've created for Sketch. We'll launch that, and we'll go into the Requirements tab, and we'll add one requirement.

We'll see from this list that PackageMaker provides a number of built-in requirements. In this demo, we'll check that 64-bit instructions are available. We'll see are 64-bit instructions available is equal to true, and then we can provide a message that will be shown to the user should this requirement fail. So we'll say 64-bit instructions required.

This software needs 64-bit instructions. We'll save our requirement. You can add as many requirements as you want. PackageMaker will add all of them together. It will also determine if they should be volume checks or installation checks. In addition, you can specify whether a requirement is required, meaning that if the requirement does not pass, the installation will not be allowed to proceed, or optional, meaning that the user will only be warned about the requirement. In this case, we'll make it required. So we'll build our package onto the desktop and run it in the installer.

And we'll see that this machine does not have 64-bit instructions, so the installation is not allowed to proceed. Now, as Peter mentioned, there might be situations where you need to modify the requirements by hand. In order to do that, you should navigate to the package in the Finder. You can Control-click and do Show Package Contents, and inside of the contents directory is the distribution.dist file, which is an XML and JavaScript file. We'll open that in a text editor.

Now the important pieces in here for this demo are the installation check element, which has a script attribute that specifies which JavaScript function to call. If this function returns true, then the installation check will pass. If it returns false, then the installation check will fail. So PackageMaker has created a function called PMInstallCheck, which uses sysctl to check for 64-bit operations. If it returns false, then the installation check will fail. If the installation check returns false, then the installation check will fail. And with that, I'll turn it back to Peter to provide some more details. Peter Bierman, Sean Kelly Thanks, Sean.

So those are package requirements. As you can see, PackageMaker, again, makes this much easier than it used to be. However, requirements are code. And generally, when an application writes code for you, you're probably going to want to understand what that code is doing, and you're going to want to look at it, edit it yourself, tweak it.

So I'm going to talk about this in a little more detail. As Sean showed you, there's the InstallationCheck element. This is similar to the VolumeCheck element, or how requirements are used elsewhere. It has a script attribute, which essentially is the contents of that attribute are a JavaScript function, or a function call. Any snippet of JavaScript, they can be true, false, one, zero. In this case, we're having it call the function that's defined in the script element. In the script element, there can be one or more script elements in your distribution. script, and they contain all your JavaScript.

So in this case, we're using the built-in JavaScript objects that the installer provides. Now, you may be familiar with JavaScript in other contexts, like web pages, obviously. And in the context of a web page, JavaScript has access to information about the web page that's provided by the web browser. In the installer, it's very similar, except for we're not providing you any information about web pages. We're providing you information about the system and the installer's runtime.

So you can see we provided some things like a log command that lets you write to the installer log. We also provide access to the I/O Kit, I/O Registry, sysctl, Gestalt, several other system functions that let you find out information about the machine. Now, you may be wondering, OK, now my JavaScript can run, and it can find out all this information about the machine. Isn't that some sort of security risk? Well, in fact, it's not, because your JavaScript can learn as much as it would like about the machine, but it can't do anything with that information other than tell the installer, essentially, yes or no, you can install.

We don't allow your JavaScript to write to files. We don't allow your JavaScript to write to the network. It's not a question of value. It's not a question of blocking these things. There's just no way to do it. There's no API within the JavaScript sandbox. So it's pretty safe.

So here we see, again, another example of the installation check that Sean showed earlier. Mine's a little different. Mine's going to check the amount of RAM that's available on the machine. Again, it's going to use sysctl to find out the physical amount of memory in the machine. It's going to compare that to 4 gigabytes. And it's going to set some values in this global variable that, again, is one of the variables that the installer runtime provides to your JavaScript. And in this case, it's myResult.

And myResult has some attributes-- type, title, and message. The type, in this case, is going to tell the installer that this particular installation check is not going to stop the install. It's just going to warn the user. And the title is going to be warning. This is going to be the sheet that appears. And the message is going to be, this package requires 4 gigabytes of RAM.

That would be a pretty weird thing to check for, but it makes a good example. In this case, my installation check is going to return false. And that's going to cause any other things that have been chained together with this particular snippet of JavaScript to not be executed.

So the first one that fails is essentially setting the global variable for what should appear in the UI, and then saying, OK, stop. Don't do any more checks. And what that looks like is this. You see a dialog. The installer says, "Warning, package requires 4 gigabytes of RAM." And in this case, they can hit OK and continue.

So those are requirements. And related requirements are the Custom Install Panel. Now, you may be asking yourself, how are requirements related to the Custom Install Panel? Well, in earlier versions of the installer, you created your user interface in the Custom Install Panel by how your packages related to each other.

The titles of your packages were the things that would appear in the Custom Install Panel, and they may or may not be selected, depending on flags in the packages. And this became very difficult, because each package actually contained information about some of the other packages. And so they weren't independent. They started being tied together in weird ways.

So what we did in Tiger is we completely redid how the Custom Install Panel works when you're using a distribution script. And when you're using a distribution script, you get complete control over what appears in this panel. You get to select what choices are that are given to the user. These are the individual line items in the Custom Install Panel. And you get to select how particular packages map to those choices. You can have choices represent zero packages, or you can have choices represent hundreds of packages. It's up to you.

And those choices, you get control over the selected, enabled, and visible states using, again, JavaScript, which ties us back to the requirement checks. So choices can interact with each other. Much like JavaScript requirement checks can find out information about the computer, about what software is installed, your choices have snippets of JavaScript that can find out the current state of other choices, can find out the current state of installed software via receipts, et cetera. So you can set up UI that says, well, if the user picks this choice, say my application, then they're also allowed to install my font. But they're not allowed to install the font unless they also install the application.

So here we see an example. What I've got is a screenshot here of a sort of manufactured custom install panel where I've got four different choices. And what I've done is I've set the selected and enabled states for these choices to map to sort of four choices as the user sees them. And so you see selected, optional, required, and prohibited. And these are kind of the four major states that you might consider your software to be in when the user is in this panel. There are other states, but you don't want to get into them.

So selected and optional is something the user is allowed to pick from. Has the user picked it? It's selected. Have they not? Well, it's optional. They're not going to install it. Required and prohibited, equally self-explanatory. Now, this particular example, I've got a choice up on the screen, the source code in the XML that sets its attributes.

Its ID is just D. Its title is prohibited. Its selected attribute is false. And its enabled state is connected to a JavaScript function, again, just like requirement checks. This JavaScript function is going to check to see if today is Friday. Today is not Friday, so the item is prohibited.

Now, these attributes are re-evaluated often. They're re-evaluated every time the user clicks on something in the Custom Install panel. Some of them are provided to be evaluated less often. For example, we give you three attributes that you can set that set the initial state, and they're only evaluated the very first time the user enters the panel or when the user switches back to Easy Install.

Now, one of the things, one of the responsibilities of this is that you have to preserve the user's intent. Because you can set the selected state, You can change the selected state even though the user thinks that they've changed the selected state. If you have an enabled control, and then the user selects it, and then you unselect it, they're going to be like, what the heck? I just clicked on that. Why is it unclicking? So to explain this in a little more detail, I'm going to bring up the demo machine.

Let's go ahead and show you one of these choices. So what I've got here are two distribution scripts just in their bare form. You can actually launch the installer this way. And I'm going to bring one of them up in TextEdit, my text editor of choice, and make it a little bigger.

And so what I've got here is just enough of a distribution script to make the installer happy. And you see I've got the-- this is the custom install panel. It's going to have four choices in it. My first choice is going to be an application. My second choice is going to be a font. And my other two choices are just there so I have something to click on.

So if I launch the installer and navigate to the Custom Install panel, what we see here is my app and my font. So the font, the enabled state is false, and that's as we expect, it's false. And the selected state is set to be equal to the application's selected state.

So this choices variable is a global variable provided by the installer in JavaScript. And you can see the state of any of the attributes of the app choice. So if I unclick the app, the font unclicks. And they'll follow each other very clearly. Selecting other things doesn't have any effect on that.

Now let's say I want to make it so that the user can optionally install the font. They don't want necessarily-- I want the font to become selected if the user clicks on the app, but then the user can unselect it if they want. So to do that-- I want to tie the enabled state to the application's enabled state. So this is very similar. I'll make it nice and big again.

Close that installer and bring up this distribution script. And so here we have the enabled state of the font is going to be equal to the selected state of the app. And the selected state of the font is going to be equal to something a little more complicated. I'll try to make that a little bigger.

So when I click on the app, the font becomes unselected and unenabled. And if I click on the app again, the font is now available. I can click on it. I can only click on it if the app is selected. What I've got here is this My Choice Selected. And if I take this out, you'll see why it's necessary.

Now what happens with this is that the app and the font are still connected. It appears to work correctly. It appears to be what I want. But if I select the app, and now, okay, well, I don't want the font. Oh, but I do want this other thing. Oh, wait, now I got the font again. Oh, I don't want the font, but I do want this other thing. Hey, I said I didn't want the font.

So what's going on here is that every time I click on something, the selected state of the font is becoming the selected state of the app. Now, it's not happening when I click on the font, because that could lead to loops. So we don't evaluate the font's choice attributes when you click on it.

The important thing to take away from this is that if you want to enforce a particular setting, it's important that you also make the enabled state false, or make sure that you take into account the user selection. Which is available by looking directly at the choice itself. Okay, so I'm going to go back to the slides.

So that's the Custom Install Panel. The Custom Install Panel can be as easy or as complicated as you'd like it to be, as you see. For example, if you look at Leopard's Install CD, you can look at the distribution script for the install CD itself, or I guess it's a DVD now. And in that is a very complicated custom install panel. There are, for example, 15 different localizations. I guess the Leopard seed is only in English, but Tiger is a good example of this.

And we make it so that you have to install localizations that you've installed previously, because we don't want you to upgrade from 10.4 to 10.5 and find out that now if you try to run in Japanese, nothing works because you only have 10.4 Japanese, but you have 10.5 everything else.

This is the kind of detail that we want you to put into your custom install panel if you really go whole hog with it. Now, you can get a lot more information about how the installer is evaluating these choice attributes. There's a secret installer flag here you see.

If you use the defaults command, you can turn on the debug engine, and all of that information will appear in the installer log, and it will tell you, hey, I'm evaluating this one, and it changed that, and so I had to reevaluate this, and it can be pretty confusing, but it can also be pretty illuminating.

So, that's the Custom Install Panel and requirements. Done in JavaScript, XML, it's pretty easy once you get to understand it. Next feature, Installer Plugins. I mentioned earlier installer plugins are the ability to insert your own user interface into the installer's flow. These sequence of panels that the installer usually presents are Welcome, Read Me, License, Target Select, and then Custom Install. If you'd like to insert a panel, for example, registration or enter a serial number, you can do that using an installer plugin.

Now, installer plugins consist of sections and panes. Sections are the things that you see on the left side of the installer. They are the bullet items as the installer proceeds. Panes are the actual content that you see on each of these panels. And so a particular section is allowed to have more than one pane.

You can have a registration section, for example, that shows up as a single bullet item on the left, registration, and that has three or four pages of, you know, tell me about your mother, tell me about your family, tell me about your dog. Your users will love that.

So here you see an installer section. I've highlighted the little bullets I was talking about on the left. This is an example we provide of entering a name accompanying serial number. So we had another example that we did last year where we actually inserted a web view, and so you could create a late-breaking news panel, for example, that would download the README for this particular version and tell the user, hey, this one's got a bug. Go get that other one.

These have, again, a section on the left that shows different panes. You can have more than one section in your plugin. You can have as many sections as you'd like. So to create an installer plugin, there's an Xcode template. This is as simple as launching Xcode, creating a new project, and picking from that big window of example templates that Apple provides, there's an installer plugin template.

And this links you against the installer plugins framework, which includes classes that implement the installer section and the installer pane. The cool thing about this is that these classes that are already there for you do 98% of the work. All you have to do is subclass them and override a couple of methods to control what you want to do.

Particularly, you can control whether your section appears at all. You can have a shouldLoadSection, I believe, is the method that maybe you don't need to do registration in some circumstances, or maybe your plugin doesn't appear if certain hardware is missing. So to show this in more detail, I'm going to go back to the demo machine.

Shortly, on the worldwide Developer Connect site, we're going to have this sample. And this was written by one of our engineers just a few months ago. And hopefully, it illustrates a lot more of the standard features that you make use of when dealing with installer plugins. So I'm going to launch Xcode real quick.

Now, let me show you before I get into this. If you create a new project, you see this window here. And all the way down the bottom, standard Apple plugins. Thank you, Expose. Standard Apple plugins, where'd it go? There it is. Installer plugins right there. So this would be how you would create one from scratch using Xcode. I'm going to start with a project that's already here because it's got a little more things set up for me.

So first I'm just going to show you what this looks like. I've already built it. I'm going to launch the installer. And first thing we see is a kind of scary-looking message that most users won't read. They'll just hit Continue. And this message says that as soon as I run this package, some code is going to run. And it's not Apple's code. It's not the installer. It's your code.

And so this is somewhat dangerous, and we hope to have some solutions for this in the future. But until then, the user clicks Continue, and they are now seeing a regular installer. And it has a section here, Registration. And if I continue, we see a registration information. So I say, I'm Peter Bierman, and I work for Apple, and my serial number is 123456789. And look at that. Oh, it's not valid. Maybe I need DAS. Maybe I need DASH, like it tells me I do. Oh, it's all better.

Okay. So that's what we're trying to build here. Not sure why that's happening? So here's our sample plug-in project. Now the key pieces here are-- this is, I think, the bulk of our source code. This is the registration pane. And there's a big license here. And it has a header.

The header's very small, and the important thing here is that our registration pane object is a subclass of the installer pane object. And then we've added a few IB outlets for our own nib. So our registration pane subclass here has a bunch of methods that basically take care of housekeeping for what this panel wants to do.

For example, when I tried to exit the pane and my serial number wasn't valid, it checked to see if my serial number was valid. And if that was no, it updated the button state. And the button state here was setNextEnabled. So this is a method provided by the installer. You could set whether or not the user is allowed to continue.

You can see it was checking to see if it was trying to continue or go back, so it only checked if I was trying to go forward, and then it put up an alert sheet. Otherwise, it said, "Yeah, you can exit the pane, and the installer takes care of the rest." So, this plugin that you just saw, very simple plugin, is something like, what, I don't know, 40 lines of code? I think you can handle that. We'll take a quick look at the nib.

NIB, also very simple. All it is is the content area of the installer. You don't have to provide any of the standard user interface that the installer ships with. The files owner is set to be an installer section, and in that, there's an outlet first pane that tells--you can have multiple NIBs and tells your section which pane is going to load first, and from there, the installer's off and running.

Finally, when you actually create your plugin, your plugin is going to end up in a plugins folder inside your package contents folder. And there's an installer section's plist that lets you control where your plugin appears relative to the other panels of the installer, and of course, the plugin itself that Xcode built. And those are installer plugins. Go back to the slides.

So, installer plugins, sort of a powerful ability for you to customize the installer's user interface. They allow users to perform all of their setup in one place. Users are sitting down and saying, hey, I'm installing software, I've got this task I'm trying to accomplish, I want to, you know, open the box and put the CD in and install the software, and okay, I'll get my registration done and I'll type in my serial number. These are all things that the user wants to do once. So if the user is doing it once, doing it in the installer, it makes sense. On the other hand, there are people out there that are doing automated setup.

The process that your user is performing once in their living room, where they want to get everything done and then be done with it, is a little different than the process that a system is performing, say, in Maine, where they're installing on something like 15,000 iBooks. They don't want to sit at the installer 15,000 times.

So, keep automated setup in mind. Your plugin should essentially work by collecting information from the user and setting that aside in a cookie for your application to find later. If your application doesn't find that cookie, your application should probably provide the same user experience, the opportunity to license or register itself at that point. Installer plugins are a convenience. They are not meant to be a gatekeeper of any sort.

So those are the features that the user deals with in the installer when they are installing your software. What do you have to worry about when you're thinking about upgrades? Now, all of you are working to ship great software, I hope. And all of you are hoping that your software is so great, you're going to have a version 2, a version 3, a version 4. You're going to take over the world.

You should be thinking about that now when you're creating your installer packages, because the installer uses upgrades to add new files, to replace existing files, to remove obsolete files-- that's a key-- and to provide a receipt trail so that the user who has installed your software and all the other software on their machine knows what they've done and can look at it later and say, hey, did something go wrong here, or did I do that? Now, the best way to deal with preparing for upgrades is to start by using a multi-package install.

And a multi-package install allows you to divide your content up into independent parts. You can have, say, an application, and a framework, and a font, and these each live in separate packages. And they each have separate versions, and they each have separate package IDs, so the installer knows of each of these things as separate things. And when you upgrade each of them, you can say, well, I only really need to change the font.

And the installer will only compare the new font to the old font, and will only remove the files that are appropriate. This is also the basis for how you set up the custom install panel. Now, it used to be that you had to create multiple packages to use the custom install panel, and the packages themselves contained this presentation information. Now, the packages no longer contain the presentation information, but the custom install panel still eventually evaluates down to particular choices, and particular choices evaluate down to particular packages. You can't have choices say, hey, install just part of this package.

So, when dealing with upgrades, another thing you have to worry about are the installer scripts. Now, installer scripts, another feature of the installer, you can create scripts that run before or after files are installed, and the scripts can be configured to run either for plain installs or upgrades. So, there's a lot of power here.

You could, in fact, install all of your software from the installer script if you wanted, and I know a lot of you have perhaps written packages that delete files or add files from installer scripts, and we want to warn you not to do that because installer scripts, in general, are going to make uninstall more difficult, and this is an important feature we've heard a lot about, and we really would like to pursue it.

So do use installer scripts to do things like start services. If I install a new program and it needs a daemon to run, then great, when my install is finished, a post-install script, spawning that daemon and getting it going so that everything's just working, I don't need to reboot, that's ideal.

Use an installer script to import modified preference files. If you've got a complicated project and version 2 of this project doesn't actually know how to read version 1's preferences, which is unusual, but it does happen, you can use an installer script to import the version 1 preference file and chew it up and turn it into a version 2 preference file, so the user doesn't lose anything.

But don't use installer scripts to create or delete files. When you do that, the installer is unaware of what your script has done. And so the installer doesn't know that that file was removed. The installer doesn't know if that file was there. The installer's never heard of that file. And so if the installer were to provide system verification or an audit trail, that's all under the radar of the installer at that point.

And most importantly, don't use your installer scripts to modify the installer's receipts. That's sort of like deleting files, but even worse. Now the installer has lost part of its brain. You've given it a lobotomy. This may be useful for you to figure out how to make your packages upgrade correctly. But trust me, that's not what you want to do in the long run. You're just sort of adding to chaos.

So another feature of the installer, particularly relevant to upgrades, and this is new in Leopard, are patch packages. Now this is something that we've had available in Software Update for a while. You've probably seen that when you download 10.4.7 and you already have 10.4.6, the download size is a lot smaller than if you have 10.4.5.

And that's because what Apple does is offer a patch package for the most recent Software Update to the one we're just shipping, and a delta, or rather a combo package that includes everything if you're installing on anything earlier than that. Now patch packages require particular software to already exist.

By definition, all they do is add things to what's already there. So they're just the delta between what was there before and what you want there now. Because of this, they specify strict requirements. They have a checksum for the files that they're going to install over, and they have other requirements to make sure they can only be installed if all of the prerequisites are met.

Now the cool thing about patch packages, and I mentioned this a little bit earlier, this is a Leopard feature, that combined with distribution scripts and flat packages, patch packages give us a feature that we call Quick Start Network Installs, where I showed you earlier, I was giving the example of the requirement checks, and I ran a distribution script in the installer, and you saw that distribution script was only like a page in TextEdit.

It was maybe 10K. You can take a distribution script and send it to the user over the internet as a bare file, and that provides you with a patch package. It provides the entire user experience, and this can download packages using flat packages, and can download patch packages.

And so now the user can get version two of your software using nothing more than a 50K web download, and then the minimum amount of download to get the rest of your software. We're going to cover this in a lot more detail on Thursday at 2:00 PM in, I think, Mission? No, Presidio. And so that's going to be a really exciting session. I hope to see you all there.

Upgrades. Wrapping this up. Upgrades the best practices. Create fine-grain packages. This helps the installer. The installer is more efficient with more packages than it used to be. It helps receipts. Use proper versions in your packages. The package version is not the same as your application version. Now, this is an area where even the new PackageMaker can't really help.

It provides a suggestion, and it actually grabs the version of your software out of your application and says, hey, the version of your package should probably be the same. I'd advise you that that's a little bit risky, because there will be times that you ship a new version of your package. Maybe there's a bug in your package. Maybe you got a requirement check wrong, and you want to roll out a new version of your package. Is that a new version of your application? That's probably not.

So keep these things separate, or at the very least, keep very close watch over what they are. The installer itself doesn't care about package versions, even when upgrading. It doesn't care if one version is bigger or smaller or letters or numbers or any of that. But there are other parts of the installer, for example, your scripts or the custom install panel, where some of the logic you write to say, is this an upgrade or not, does care whether one number is greater than another. So I strongly advise you to use regular just numbers and decimal points.

Keep consistent package IDs. Don't change your package ID with each release. For example, don't put your version number in your package ID. The package ID is how the installer knows how to do an upgrade. It looks and says, hey, this package is package ID foo. Did I ever install package ID foo before? And if it did, it finds that in the receipts, and it does a comparison. It says, these are the files that used to be in foo. These are the files that are in foo today. And it uses that information to decide which files to delete and which files to add.

If you delete receipts, or if you change package IDs, you subvert this mechanism, and the installer slowly gets confused and thinks that either more is installed than really is, or less is installed than really is. And we want to make it possible for the user to look at the installer's database to see how their system is configured. So we trust you to provide useful and valid information. Finally, all of that boils down to inform the installer. Don't bypass it. Don't work around it, because really, you're working around your customers. Your customers want to know what's on their machine.

They want to be able to see, did I install this correctly? We might provide other features in the future that check to see if things are still installed correctly. And so the more and the more accurate information you provide the installer, the more powerful we can make it. So those are upgrades.

To summarize the entire presentation, we want you to pick your delivery mechanism. You've got disk images, zip files, and starting in 10.5, flat packages. Think about what your customer wants in their installation experience. Are they the kind of customer that understands disk images and drag installs? Then that's what you should provide. If your customer wants more of a handheld experience, use the installer. Start using PackageMaker 3.0. PackageMaker 3.0, new in Leopard. We've put a huge amount of work into it, and we're really happy with it.

Support relocatable applications. Apple themselves has been kind of sketchy about this in the past. A lot of it has been because how difficult it's been to create the file that the installer needs that understands how to find your application on the hard drive. With PackageMaker 3, it will create this very difficult to understand file that works on 10.4, and it will create this new syntax that we're introducing in 10.5 that we'll cover in more detail on Thursday. Much easier to support this both at the low level and at the high level.

Create packages for each of your components. Fine-grained packages allow you easier control in the custom install panel, make the installer more efficient. Don't trick the installer. Don't hack receipts. Don't delete receipts. Library receipts, it's our database. It's not meant for people to play around in. And don't create or remove files using scripts. Again, don't trick the installer.

Finally, send us your feedback. We have a whole lot of new features in Leopard. We're going to have an entire another session on Thursday. I mentioned this a couple times. That session is going to be nothing but new features in Leopard in the installer. So, we want you to play with those. Tell us how they work. Tell us if they meet your needs, and send us your feedback, ideally as soon as possible, because the sooner we hear that feedback, the quicker we can roll those changes into Leopard and get them perhaps out with 10.5 itself.

So, to learn more about all this stuff, we have two lab sessions this week. We have one this afternoon at 2:00 PM. I think that's pretty much after this session. We have another one Thursday at 5:00, which will be after our other presentation. We have a bunch of documentation that's available on the Internet.

We have a brand new software delivery guide. This was just produced by our Technical Publications Department. It covers all of the things I've covered in this talk and a whole bunch more. And it's available at the URL that you see up there. We also have the Installer Release Note. This goes into detail about the syntax for distribution scripts and the JavaScript APIs that are available inside the Installer. And that Release Note is available both on the Internet and it's installed as part of the developer tools in the standard Release Note area.

We also have a public mailing list. This has really taken off. We introduced this, I think, about a year ago. Several dozen developers working on their packages, working on their products. Not a very high traffic mailing list. It's not like people are making new packages every day. But when people run into little glitches with the installer or they want to know, hey, how did this work on 10.3 versus 10.4 versus 10.5, this broad collection of people helping each other is really an improvement. And finally, there's the example distribution script that's used to install the OS itself, which is on the installer DVD at systeminstallationpackages.osinstallmpack agecontentsosinstall.dist.