Application • 1:03:25
This session will teach you how to use the Mac OS X installer technology and introduce new top requested features. We explain how you can build an installer for your application, make your own installation packages, and personalize the installation experience using custom panes.
Speakers: Jean-Pierre Ciudad, Jack Matthew, Christopher Ryan, Peter Bierman
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Welcome to session 403 regarding the Mac OS X installer application. My name is Jean-Pierre Ciudaad, and I work at Apple in the installation and setup group. We write applications like the installer application, the software update application, and the setup assistant, which is the first application you see after installing the OS once you reboot the machine.
First, I have a question for you. How many of you are familiar with creating installation packages? Okay, maybe 60%, 70%. So, for those of you who are not familiar with creating packages, I'm gonna start by giving you an overview of what are the options available for you on Mac OS X. For those of you who are familiar, after the overview, we'll talk about some of the new and updated features that we are bringing to you in Tiger. Most importantly, we'll talk about installation plugins and distributions.
Then we'll talk about how you can create compatible packages that will install all the way from 10.1 to Tiger. And at the end we'll talk about where you can find some more documentation about all these things. There are two types of installations that are available to you on Mac OS X. The first one, drag and drop installs. This is the simplest way to deliver your application to your users.
In addition to that, Apple also provides you with an application called Package Maker to create packages and the installer application to install them on the user's machine. So let's start with drag and drop. What are the advantages? Well, the advantages to users are obvious. It's only one file, one application bundle that your user can just drag to wherever he wants in the file system. It's very simple to install. It's also very easy to remove. The user can just grab the application bundle and drag it to the trash.
The advantages for you: there is absolutely no complex installation instructions to write. It's a very simple process.
[Transcript missing]
Your application will need to handle any README, any license agreement. It will also have to check for proper configuration when it's launched. Again, you have no way to do additional checking.
[Transcript missing]
So you may have noticed that one of the first panel that you see in the setup assistant is a migration panel that asks you if you want to migrate from another machine or from another partition. When we do this migration, we do not carry over files that were installed into Slash system. Or to be more precise, we do it, but we do it on a case-for-case basis. So if we don't know about your file, it will not be migrated.
So you may have noticed that one of the first panel that you see in the setup assistant is a migration panel that asks you if you want to migrate from another machine or from another partition. If your application needs to restart or needs a logout, we will ask the user to restart or to logout. We will also do the optimizing system performance section of the installer, which is we will run the pre-binding tool to pre-bind your executable.
If you're installing an application, we will register it with Launch Services, and we will also allow you to provide some customizable parts of the UI, namely the welcome panel, the background image, and a localized readme or license agreement. So, how do you, sorry, what is an installer package? So first and foremost, an installer package contains the files that you want to install. This is what we call the payload. The payload is just a Pax archive.
In addition to that, a package bundle contains a catalog. The catalog is a bill of materials. It's an index list of the files that are contained in your archive. In addition to that, you provide a description file that gives us the title and the description of the package.
Also, you provide some flags that tells us how to behave. Do you want an authorization and things like that? Do you want to follow sim links? Then you also provide all the UI parts of the installation process, the background image, the readme, the license agreement, the welcome screen. You also provide the check tools that will check the system to make sure that your package can be installed on, and same thing for the volume, the installation check and volume check tool.
And then you provide a collection of scripts that you may want to be run before you install the files or after you install the files. We make a difference between pre-install and pre-upgrade depending if you're doing an upgrade or an install, obviously. Now you can create as many packages as you want, and then you can group them together in the UI by using a meta package.
An installer meta package structure is very similar to a package, except that it does not contain any payload. Its only purpose is to group things together in the UI. The way you list those packages, the packages that belong to this meta package, is by adding a key in the Info.plist that will contain the list of packages. Now, a meta package also contains some UI sections, the check tools, and the different scripts.
So how do you create a package? You create a package using Packagemaker. Packagemaker is installed on your system as part of the Xcode tools. It's installed in developer application utilities, and you can run Packagemaker as an application, or you can also run it as a command line tool that you can include in your build scripts.
As it is today, on your CD, on the Tiger CD that you have, the PackageMaker is a very simple version of the application. It only creates very simple packages. You will most likely have to go and edit the files that get created in order to support some of the more advanced features of the installer. However, we are actively working on PackageMaker, and we really hope to deliver to you a much better application of PackageMaker for GM.
So in Packagemaker, you provide the root directory of your software, you specify the different installation flags that you want to use, and you give us the name of your package, the description, and then the location of all the additional files, like the readme, the license agreement, etc. On output, Packagemaker will create a package, a .pkg bundle, that you will distribute to your users.
That package will be installed on the user's machine using the Apple installer, which is located in Application Utilities. The installer has been shipping in every single version of Mac OS X. It's always available. Users are familiar with it. It's very easy to use. So now I would like to introduce you to Jack Matthew, the field shearer of installation.
and he's also the person at Apple who made a career out of creating installer packages. Jack? Thanks a lot, Jean-Pierre. My car isn't nice as Phil's. I drive a Toyota, so not quite as -- not quite Phil. So as Jean-Pierre mentioned, PackageMaker is a really simple application. The things that you need in order to use PackageMaker are, first of all, a root, and you can think of this as slash. And let's just take a look at our root here.
Oops. And So our root contains applications and then our application. And one of the reasons we might want to use a package based installer is because we're installing more than one thing on the file system, otherwise we'd want to use a drag install. So we also install something into library application support.
So in addition to the root, we also have this package resources folder. And it contains, let's say, a post processing script that we would want to run. It also includes Lproj folders that contain our localized resources. So in this case, I've got an English readme. And in honor of Jean-Pierre, we've got a French Lproj, the French readme. And so now we can begin actually making our package. So let's go ahead and launch PackageMaker. Really simple UI. So title, let's call it My Application.
Oops. Version 1.0. And description. Description is what appears in custom install if this package is included as part of a meta package. This is good. OK. So files. This is where we select our route. So where is that? I've got it right here. There's our route. Resources. Here are the resources.
and Info, this is where you can set up some of the meta install flags. In this particular case, we're installing an application and something into application support. So you're going to want to have admin privileges, otherwise it's not going to work if you have a really restricted user that's running the package.
So that's actually all there is to it. So let's go ahead and create package and we'll call it. MyApp.pkg. And we'll go ahead and put that on the desktop. Ta-da, that's it. So we can go ahead and launch the package. That's all there is to it. And I'm going to turn the stage back over to Jean-Pierre.
Thank you, Jack. So this is very simple. You know, there's not much to it. This is very useful. So now I would like to talk to you about our new features. So first, where do we get ideas for new features? Well, we mostly get them from you. You send us feedback, we meet you at WWDC, you report bugs.
Often they're more announcements requests than bugs, and sometimes they are real new features, and we listen to what you have to say. We also listen to people like Jack, who create packages at Apple, who create packages for DOS and also for applications. They are a great source of information for us, and we are, please keep the feedback coming.
So what have we done in Tiger? So here are some of the new features that might be of interest for you. File version checking. Some of you may be familiar with bundle version checking, which is what prevents the installer from overriding a newer version of a bundle on the user's disk.
We have extended that to files. The reason for that is because some files are not part of a bundle. Things like fonts, for example. And currently what our installer would be doing is that it would just go and install an older version of the font over a newer one.
So this is bad, so we decided to address that. It works in a very simple way. For every file that you want to check, we give you a hook where you can provide your own tool and basically tell us whether or not the file should be replaced. We are gonna provide some standard ways, some standard version checks for some files.
Multiple CD installations. That's a request that we heard last year that a lot of people wanted to be able to actually, they wanted the installer to be able to handle multiple CDs or multiple DVDs, so we now have implemented that. It will be available through distribution scripts. You will hear about distributions later.
Minimum UI Installation. So this is in order to provide a better solution for automated installs. We now allow the package writer to specify if some panels in the installer should be skipped. We also provide, for some of the panels, we provide a minimal UI, which means that we do not force the user to always answer a question in the installer panel. We can assume certain replies.
So it's useful for automated install. It will also be available through distribution scripts. Application selection. One of the panels that you have in the installer today is target selection, where we list all the volumes that you have on your machine. This is great when you're installing the OS, but really when you deliver a new version of your application to the user, you want to upgrade the existing one. So what application selection is, is a replacement for volume selection. Instead of disk, you will see older versions of your application on the user's machine, and the user can say, this is the one I want to upgrade.
And then we have two more features that I would like to call, two more features that I would like to go into more details. And for that, I'm going to call two engineers in my team. And we're going to start with plugins, installer plugins, and I would like to call Chris Ryan.
Thank you, Jean-Pierre. So, I'm going to talk--my name is Christopher Ryan and I work on the setup and installation team, and I'm going to talk about installer plug-ins. So--oh. Installer Plugins. So, I'm going to talk about why we have installer plugins, what they are and how they're used, how to create an installer plugin, some requirements, when they should be used and when they shouldn't be used, as well as some demos. So let's get started.
Why do we have installer plugins? So as Jean-Pierre mentioned, there are many ways to customize your installer's experience. You have a readme, a license, a welcome panel, as well as a custom background. But we've been hearing requests from many developers that you want to do more. You want to do things we haven't thought of. You want registration, serialization, maybe even a summary or conclusion at the end of the install. And so we're going to provide you some plugin support so you can do this.
So what are they? They are a customizable section in the installer, similar to how you see the README and license and the target select panels. They're provided by developers inside your packages or distributions. They are loadable code, which can have nibs as well as other resources you need. But to best show you these plug-ins, we're going to bring Jack Matthew up to show you a quick demo.
Jack. Thanks a lot, Chris. So again, this is just best seen. So let's go ahead and launch a package that is using a couple of custom plug-ins. So the first thing you might notice here is on the left, there's some more stuff. So, Let's just go ahead and continue on to one of these custom plugins. Here's a registration plugin. This is what we call a section, and we're going to go into more details in a moment. But let's go ahead and fill this out.
and then we're going to enter our serial number and you might notice that the continue button is grayed out until we enter our extremely secure product key. and then we're going to enter our serial number and you might notice that the continue button is grayed out until we enter our extremely secure product key. and incidentally your various plugins can talk to each other through a shared dictionary.
Here we go. And we're done. Yay! And look at this. This is an example of a late breaking news plugin. You might want to just give someone the latest information off of your own webpage. This is just something we were able to make really quick. So you'll see over here, breaking news. and Casey didn't notice the installer window is resizable now, which is nice. That is a package with two custom plugins. Back over to Chris. Thank you, Jack.
So as you can see, you can customize the installer's experience. How do we do this? So we have an Xcode template now in Tiger, which will create a very basic plugin you can use to extend. We have a new framework called the installer plugins framework, which contains two new concepts that Jack alluded to, the installer section and installer pane. I'm going to go over those in a second.
So here's the window that you saw that Jack showed on the screen with the late breaking news plugin. Each plugin contains one section. So here's the registration section. It's provided by the registration plugin. It also contains two panes. and the Late Breaking News section contains one pane, so you can have one or more panes per section.
In an installer section, you can customize a few things. One is the title. This can be either dynamic or static, so you can decide the title at runtime. You can also decide whether to actually show the section or not. For registration, for example, you may not want to show the registration section if your product is already registered on that machine. Also, you can decide the panel ordering at runtime from your section. So here's the example registration section, and the title, which you can customize, is highlighted.
How do we do this? You can customize the title of your installer section using the installer section title key in your Info.plist file. And this is localized using the Info.plist.strings file. Also, you can do this at runtime by using the installer section's title method in the installer section subclass. And to subclass an installer section, you need to provide the NSPrincipleClass key in your Info.plist so the installer knows exactly which installer section class to load.
And then we also have a very important method called shouldLoad, which allows you to decide at runtime whether your section should load in the installer's UI or not. So here's a quick example of the shouldLoad method. In this example, we have a section that should only run on a machine with one gigabyte of memory. So as you notice, you can use syscontrol or any other system libraries to decide whether your section should load or not.
And it checks for one gigabyte of memory, and if there's one gigabyte of memory, it returns yes. The installer will load the section automatically. Otherwise, it's not loaded. The real meat is the view and what you see on the screen. So you can customize this using an installer pane. The installer pane provides a title, just shown here at the top. Provides the content view.
[Transcript missing]
and there are also some entering and exit methods, will enter, will exit, did enter, did exit, as well as a very important should exit method which gets called when the user clicks the continue or go back button on your pane so you can decide whether you want to exit the pane or not at run time.
So here's an example of that. So in this example, you may want to warn the user that they have to--that they might have--we might have to send their registration over the internet. And so when the user clicks the continue button, we're we're going to The installer is going to call the should exit pane method on your pane, and you're going to return no and show an alert warning them that we're going to send their registration. And when the alert's complete, there's the installer pane's go to next pane method, which you call to advance to the next pane.
The installer is going to call the should exit pane method on your pane, and you're going to return no and show an alert warning them that we're going to send their registration. And when the alert's complete, there's the installer pane's go to next pane method, which you call to advance to the next pane. Each of the installer sections are installer plugins. So let's show you how to create one of these. Jack?
[Transcript missing]
Each of the installer sections are installer plugins.
[Transcript missing]
I'm going to go ahead and paste in this code. And this is going to, believe it or not, just going to make us a very, very, very simple, basic plugin. This is the should exit pane method that Chris mentioned. This is going to get called by the installer when you click the continue or go back button.
And we're going to use this to present a goodbye message before the user actually is able to go to the next plugin. So we'll go ahead and save that. And then we're also going to go into the nib and add some hello world text. OK, so here's our content view.
Save. And let's go ahead and build it, see what happens. Okay, and I believe we are done. So let's look at, I've got a package ready to go here to take our plugin. Just copy this to the desktop in case. Okay, show package contents. and here's the contents folder. Now you're going to need to create a plugins folder inside of contents.
So, as Chris mentioned, it's going to need to contain two things. The first is, of course, your plugin bundle that you've built. The other thing is the installer section's plist file, and that determines the order of your plugin relative to the
[Transcript missing]
Here's our bundle. And that should be it. Now let's go ahead and double click our package and see what happens.
Now I didn't change the installer section's plist file, but if we wanted to have our hello world be first, we would have done that and we could have made it first. Can you read me? And there you go. And so let's try to click continue and goodbye. And that is a simple plugin.
Thank you, Jack. As you can see, it's pretty easy to create an installer plugin. So, some of the requirements and restrictions on these plugins. First of all, installer plugins are only available on Tiger. So if you make a package and you include an installer plugin, these plugins will be ignored on previous builds. What this means is that you shouldn't rely on your plugins for serialization of your application or for registration.
You should use this as a helper to get the best user experience for your customers while they're installing. Also, it's important to note that now we have a new feature in the installer in Tiger, which is multiple CD or disc DVD installs. And with this, that means that your plugin's resources may not be available at all times. So it's very important that your plugins do not access their resources or data while they are not currently active or not being, methods aren't being called from the installer on your plugins.
So with that, I'm going to hand it over to Peter Bierman, who's going to talk about distribution scripts. Peter? - Thank you, Chris. I'm Peter Bierman. I work on the installer team with Chris and Jean-Pierre and some other people. I'm gonna be talking about distribution scripts, another new feature we have in Tiger. Pretty excited about this. It's gonna give us some cool new features.
So distribution scripts are all about controlling the installer's user interface. I spend a lot of my time advising developers that if they can, they should use a drag and drop installer, but often they can't and it's because they have a more complicated piece of software. Usually as their software gets more complicated, they move into using what we call M packages or meta packages that Jean-Pierre talked about. And when you start using meta packages, it gets to be difficult to control the installer's UI. The good thing about using the installer is that you get a consistent user experience. The downside of especially meta packages is it's hard to create that consistent user experience.
So here's the diagram of the installation package that Jean-Pierre showed you earlier. As you can see, there's lots of little files you have to keep track of. In particular, this section in the middle is all the user interface controlling files. Lots of flags, lots of keywords, things that have been added over the years. When you start to deal with meta packages, you have all the same packages and all the same flags. They're just scattered everywhere.
So we've created distribution scripts. Distribution scripts take all of those flags and move them into a single file. Hopefully it makes it easier for you guys to create your packages, keep track of how the user interface is going to look when the user is using your installer. So how do we do this? We're going to use XML and JavaScript. We've decided to use XML because it's easy for machines to read and write, and because we're using application specific elements, it can be easy for humans to read and write. We're also using JavaScript.
JavaScript looks like C, but it has a lot of cool features like garbage collection and associative arrays. It makes some things a lot easier to deal with. It's also sandboxed inside of the installer application. That means it's not going to be able to do anything else. So we're going to use the Mac OS X installer technology and introduce new top requested features. We're going to use XML and JavaScript. We've decided to use XML because it's easy for machines to read and write, and because we're using application specific elements, it can be easy for humans to read and write. We're also using JavaScript.
JavaScript looks like C, but it has a lot of cool features like garbage collection and associative arrays. It makes some things a lot easier to deal with. We're also using XML and JavaScript because it's easy for humans to read and write. It makes some things a lot easier to deal with.
Well, you'd have a file. It can be called anything. We've gotten away from those package-based file names. It has to have a .dist extension. It ends up in the contents subfolder of your package or mPackage. And within the distribution script itself, any of the strings you use that are user interface items can actually be keys for the localized strings elsewhere in your package bundle.
So let's take a closer look at distribution scripts. Here's some of the beginnings of the distribution script vocabulary. You can see here there's the first element is installer GUI script. This actually is the container element for all the other elements used inside the distribution script. Then we see a title element which within the title element contains your title, your package title, and a welcome, a read me, and license elements. These use a file attribute to specify a file located in your package resources much like there are flags for these same things in the current installer package format.
Things get a little more complicated here. We have a package reference element. This has an ID attribute that's used to refer to the package reference element elsewhere in the distribution script. It also has a kilobytes attribute, which will be used by the installer UI to show how big your package is, this particular package. Finally, there's a file URL here for where the installer framework itself will go and get your package when it comes down to do installing.
One of the interesting things about this is what you're seeing here is the beginnings of the installer doesn't actually need to look at your packages to present any of the UI. It's actually going to try to get as much of this information from you up front and then hand your list of packages to the framework when it's done.
So, when we get to the UI, we get to the custom install panel, and things get even more interesting. Here we see a choices outline element. This is the beginnings of you setting up what exactly that custom install panel should look like. There's two line elements here. They refer to two choice elements named app and extra. These names can be whatever you want.
The choice element, the first choice element here, we've called app. It has a title. In this case, it's not localized. It's just right in the distribution script. And it also has within it a connection to the package ref element you saw in the previous slide. And we do that again with the extras item. So you put those two together and we end up with a very familiar custom install panel. There's nothing on this screen that you can't do yourself currently with packages or mPackages, but it's a little simpler to do with distribution scripts.
and we can throw that all together. Here's the whole thing, all of them combined. You can see the various choice elements, line elements, how they all are connected to each other. So that's what you can do today with a new syntax, XML file, yeah, it sounds great. But there's a bunch of cool new things you can do with it.
For example, you can now attach multiple packages to any one choice. You can break up your software in any way you want and connect the things to the choices the user sees in the UI completely separately from how you package your software. You can attach the same package to different choices.
You can have some app support package that never changes that's attached to all the various things that the user could install. You can show the same choice in more than one place. You could create a very creative custom install UI where you've got groups of things and, well, you can use your imagination there.
and you can enable or select choices based on the user's other selections inside the customization panel and the system configuration. Now, with M packages, you can do this, but it's difficult. There are flags and most of it involves packages ruling themselves out because they don't like how the machine's configured or so on. With distribution scripts, it's much more explicit. You have very complete control over whether a package is enabled or disabled, selected or deselected.
So how do we do that? Well, we have these choice elements I showed you a few seconds ago. And the choice elements represent the choices a user can make inside the customization UI. The choice elements have attributes like selected, enabled, and visible. And the values of those attributes can be JavaScript expressions.
So here we see again a very simple representation of the custom install panel. And let's take a closer look at those two choices. A very common idiom is for people to have an app in some dependent package. Or they want these two things to be related to each other. For example, if I deselect the app, I want the extras to become deselected and disabled. So the user can't install the extras separately from the app. I reselect the app, the extras become enabled, et cetera.
So how would we do that using a distribution script? Here we see the choices outline again that just sets up the outline view. And we see our two choices, our app and our extras choice. In the attributes for the extras choice, we have an enabled attribute and a selected attribute. The enabled attribute is a JavaScript expression. It's choices.app.selected. Now that refers back to the app choice that's in the middle of the screen there.
That choices word there that's in that JavaScript expression is actually an object that's provided by the installer's runtime that allows you to connect to the attributes to the choices declared in XML. These are all the attributes of the choices are dynamic at runtime, so when the user checks something, you can determine whether it's checked, which one's checked, whether it's enabled, things like that.
The selected attribute is a little more complicated. In this case, we want the user to only be able to select it if the app is selected. So that's that first half of that and expression there. The other half of it is sort of self-referring. What that means is that if the app is selected, the value of the selected attribute of the extras is equal to whatever the user wants it to be. If the user clicks it, it's selected. If the user unselects it, it's deselected.
And again, that choices object is provided by the installer runtime, connects you to all the live state of the various choice elements. Now, there's a couple other objects that we provide in the installer runtime, and I'll talk about those. So here we have the JavaScript system object. This is, again, provided by the installer's runtime.
It contains a bunch of methods and static data about the configuration of the machine. It lets you inspect that from your distribution script. And it's read only. You can't go into it and change things about the machine. You can't say, oh, the machine has two gigs of RAM now. That's not going to be possible. But you can use things like sysctl. You can get the values out of a plist anywhere on the file system. And you can use the I/O registry to find out if your hardware is connected, for example.
Here's an example. We can set up our application to only be enabled if the machine has 128 megs of RAM. Here you see the enabled attribute of the choice, of the app choice. It's connected to a JavaScript function that we've named has 128 megabytes. And that function's contained within a script element. You can have as many of these script elements as you'd like within your distribution script.
And you can put any JavaScript you'd like inside these script elements. Here we have a function that I've written has 128 megs of RAM. It uses the system.sysctl method to find out how much physical RAM the machine has and returns yes or no depending on whether there's enough.
So that's a pretty quick look at some of the neat things you can do. Jack's gonna look at some of the more advanced things we can do with it. Jack? Okay, got the clip on too. So, first let's just go ahead and dive into a package that is using a distribution script and look at something that you've never been able to do before. We're really excited about this. Okay.
[Transcript missing]
So first off, just going over what Peter showed you in the slides, You can do this. Again, this is a very common idiom. Say you had a font that needed to go with your application and you wanted to provide this kind of optional install here, but the font's no good without the app. Something like that you can do now. Now, let's look at this.
This is a little more interesting. You'll notice that I clicked on this, but you see something happened in here. - All right. - So let's go ahead and... We look at this expanded here and you'll see that as I click these items, other items become selected. Finally we can do stuff like this. This is great. So let's look at another example.
and the rest of the team. So, well this isn't very interesting, is it? But let's just go ahead for a moment and look at the code for this. This is, let me introduce you to the first JavaScript I've ever written, literally. This took me minutes to figure out.
It's very, very, very simple. So we have some standard stuff in here like has a welcome.rtf. Okay, fine. Then we start talking about here the choices, the line items that appear in the custom pane and the custom install UI. And then we begin to actually accumulate information about each of these choices in a few different other XML tags here. First we're saying here, here's choice that we're referring to as A. It's got a title. It's called Nifty Application. Then we have a choice called B.
B has a title as well. And we're saying that it's enabled. You can select this package. But here's another interesting field here, Start Selected. What is the default selection state of this choice? Well, it's a function. So what does this function do? Well, we've gone and embedded some JavaScript here inside of this XML tag. Has cookie. So say you wanted to, say your application goes and lays down a cookie file, and then on subsequent use of an installer, you don't want to present that option by default. So on easy install, a more reasonable thing happens.
So, simply here, I go ahead and use the built-in system object, system, files, file exists at path, and then I give it a path. So, let's go ahead and, for fun, go ahead and create that path. Permission denied. I've been denied. We have our ways. Oh. - Uh oh. - Perhaps we don't. Okay.
Well, I assure you that if I had successfully authorized here, that upon second launch of that package, we would have seen that by default, that optional item would have been deselected. So that is a quick demo of distribution scripts. And I'm going to hand the stage back over to Peter.
Thanks Jack. We actually tried a lot of this stuff earlier today and something's got to go wrong during the actual presentation, so there you have it. So if you do these, if you work on these, there's a couple things you should watch out for. Both XML and JavaScript are case sensitive. If you run into some mysterious problems, you're confused, try using user bin XML lint.
It's included in the system. It'll look through your XML, point out any problems you have, missing characters, missing slashes, things like that. One of the most common things you have to watch out for is there's five characters you have to escape in all XML documents. That's the left and right angle brackets.
The single and double quote and the ampersand. If you decide to write some software or some scripts to create distribution scripts for you instead of doing them by hand, you can use a function such as the CF function, CFXML, create string by escaping entities. That's a mouthful. But beware, that function has a bug in 10.3. It doesn't make it very useful, but it is fixed in the tiger build that you all have. You can also use similar functions in your favorite scripting languages.
So, distribution scripts. This was just a teaser. We hope to, by the GM version of Tiger, have what we're going to call a package translator that will look at your existing M packages and build you a distribution script so you'll have something to start with. There's also a session download that's available on connect.apple.com for this session that includes a documentation, a test app to play with distributions, and some sample distribution scripts.
Unfortunately, the installer that is in the Tiger build that you all have doesn't currently deal with distribution scripts. We're in the process of building them up and adding more support for them. So, now's a great time for us to hear your feedback about it. It's still under construction. Please play with it and send your feedback to installer-dist-feedback at group.apple.com. and now the man you've been listening to all through the session, Jack, is going to come up and give his presentation on building compatible packages. Jack.
Hello, hello, hello, hello, hello. Is the mic on? Okay. So, let me formally introduce myself here. My name is Jack Matthew, and my team at Apple are Apple's... Can we get the slides on, please? So my team are Apple's package developers. We're like you guys. We work on the OS install, the OS updates, the iLife applications, the Pro applications such as Final Cut, DVD Studio Pro, a bunch of other little random small updates like security updates. We also help keep software update running.
And we work on the Windows installers as well. So I'm here to talk about compatibility. We've seen some really great new features here today, but if you're like us, you have to deliver software to people that have older machines. So let me just go over what I'm gonna talk about here.
First of all, making packages that work with both 10.1 as well as Tiger. We're going to talk about some of the things that have happened to the package format over time, go over some features that you may or may not be aware of. We're going to talk about if your application or if your package really must use some of these new features that we've been talking about here, that if someone gets a hold of that on an older system, that the right thing happens.
And then we're going to talk about packages that are a little bit more complicated. They use things like custom install and a mixture of some of these new and old features and kind of how to get the best, make some compromises, and deliver something that's going to work for the maximum number of people. So, first off, simple packages. What do I mean by that? Packages that basically just install your bits. Little more than that. Maybe they run a pre or post processing script.
So the first thing to understand is that a package that you built on 10.1 is still going to run when you launch it on Tiger. And similarly, if you built your package using PackageMaker on Tiger, it's going to run on 10.1. and if you need a little bit more functionality in your script, the installation check and volume check scripts as well as the pre and post flight scripts still work in Tiger and work all the way back to 10.1. and if you need a little bit more functionality in your script, the installation check and volume check scripts as well as the pre and post flight scripts still work in Tiger and work all the way back to 10.1.
So 10.1, something called myapp.pkg. As you can see, especially in the scripts up there, my app is attached to a lot of these resource names. and We dumped that in 10.2. In 10.2, packages became a real NSBundle and they have things like an info P list and all the resources inside of that package have a consistent name.
This is good. This is good because, well, first of all, for users, if they rename that package, it works. It used to break. Consistent file names are really useful for things like automation. And Apple localizes its software into 15 different languages. A nice little bonus that happened was that by separating the meta install flags from things like the description and title, now we no longer have some of these meta install flags accidentally localized for us. So that was a nice little thing.
Additionally, the payload and catalog files, that is the bill of materials and the archive, changed in file name only. So under the hood, they're the same exact files. So what PackageMaker does for you is create symlinks that when you run that package on an older system, it's tricked into the right thing happening.
So, some features and changes here. In 10.2, we added a feature called Find Files. And Find Files is useful for updating your application in a location that the user may have moved it to. We use this extensively in all the OS updates because we only ship parts of each application. We don't reship mail when we want to update it. Just a little bit that changed.
So, we use it quite a lot. We depend on it. We also added the background pictures feature, which allows you to include custom artwork for the installer to display. And in 10.3, we made that Find Files feature a little bit easier to use. And another notable thing for app package authors here is that we enhanced the Follow Sim Links feature so that if those Sim Links point to things on other devices, that it works. and on Tiger for application package developers, there are more features that apply to you guys than any other OS release.
So, I also wanted to mention some things that you should be aware of if your application has to work on 10.2 or earlier. Now, these are things that we've fixed in 10.3, but things to keep in mind, and we'd just like to mention them really quickly here. So, first of all, when you make your root, make it relative from slash.
In other words, if you are creating an application, if you are installing an application, your root should look like root, and then applications, and then your app. This is as opposed to just selecting the app as your root and changing the default location inside of PackageMaker. This actually gets around a few little edge case bugs, and is especially important if you're using the find files feature. What you expect would happen might not happen if you don't do that.
Additionally, make sure that in your root, the permissions are correct. It should be, you know, 1775 for your root, and so on. This is because there's a bug where on upgrade installs, the state of the overwrite permissions flag is ignored. So, you reinstall the package a second time, it's going to make the permissions be whatever was in your root, which might not be what you want. Additionally, meta packages do not run the installation check tool. So, simply include that logic inside of a packages installation check tool. And again, all this stuff works in 10.3 and in Tiger.
Tiger-only packages. You need to use the distribution scripts. You need to use plug-ins. You want to make sure that if someone gets a hold of that on a 10.3 or earlier system, that they're not able to install that package. Because remember, the 10.3 and earlier don't understand what a distribution script is. So what do you do? So you include an installation check tool that is going to exit with an error value. And then on Tiger, the distribution script is going to take precedence.
So you put your real requirements inside of your distribution script for your Tiger or later customers. And on the older systems, installation check gets run and it just exits with an error. And one nice thing about this is that it doesn't require any special strings files. It's going to use a generic error message built into the installer. So it's going to be localized for all languages. As you can see here, it just exit with the value 96. Very, very simple. It's just with bits 5 and 6 set.
So, packages that use some more advanced features and are still compatible. So, as I mentioned before, you can include a distribution script as well as installation check and volume check scripts. The installation check and volume check scripts can, of course, meet the requirements for your 10.3 customers, and the distribution script is going to get run on Tiger, and you can take advantage of some of the more subtle controls, like the default selection state, for example. Probably some of you have seen this. Even if the installation check and volume check script meet your needs, you should also, or you can also, include a distribution script, and on Tiger systems, it's gonna get rid of this user interface.
So, distribution scripts, again, are a place where custom install is, when we talk about custom install, we talk about distribution scripts. So, there are a few things to keep in mind here. A package or a meta package is a line item in custom install for 10.3 and earlier. You're going to have to package around this.
Now, there's nothing that says that you can't make a little bit more subtle behavior in 10.3 or in Tiger and have a slightly different user experience. There's nothing wrong with that. And also keep in mind that the check scripts can only skip packages. Can this package be installed at all or not? And, again, you can't affect the default selection state.
So, moving on to file version checking. File version checking provides a really nice framework for you to check versions of files. Now, if you really have to check the version of a file, there's nothing that prevents you today from taking advantage of the pre- and post-flight hooks to run your own code and do the right thing. It's more effort, but hey, you can still do it.
Multi-CD installation is another great new feature. Now, on Tiger, you can use distribution scripts to make everything happen and have that nice user experience for Tiger customers. And for pre-Tiger customers, you can simply include extra meta packages on each CD that guide the user into installing. For example, install me first .mpkg, install me second .mpkg, install me third .mpkg. The important thing to remember here is that you don't actually have to repackage your bits. The .pkgs are the same thing. You're just including this extra little thing that make it work.
[Transcript missing]
The pre-Tiger installer ignores plugins. You can include the plugin and it will run for Tiger customers. What we recommend that you do is if that UI is really important, to move it into your application and on first launch, display it. This is a really obvious use for these plugins as some sort of product key or serialization.
Now, you should keep in mind that someone can always go in from either the command line or third party tools and just pluck the contents out of your package. It's not secure. It's not going to be secure in that way. It's not a real gateway for copy protection. So you should move that kind of stuff into your app anyways.
Here's a screenshot. This is the Final Cut Express installer and you can see some user interface that kind of looks like it's part of the installer. It's not. It's its own application. We don't recommend that you do this, but it is possible. This particular example used the volume check hook, and the installer is just running an executable, so your executable can be as clever as it needs to be to kind of pretend that it's a part of the installer. Again, don't do this if you can avoid it. There are a number of edge case bugs. It just doesn't integrate well.
So, to summarize what I've talked about, some of the things that you should remember to take away from this. So, with regard to compatibility, Packages that you made will still work. Packages that you make in Tiger can still work on older versions of the OS. And this is all true if you use PackageMaker as a starting point. Now, it doesn't have a lot of features. Hopefully we can add those over time, but still use it as a starting point. It's going to create the basic structure of a package that's going to be compatible.
Now, as you saw in the 10.1 package diagram, there are a lot of other little names attached to the various resources, with the exception of preflight and postflight. So if you use preflight and postflight across the board, it's going to work everywhere. and finally you can use a mixture of both some of the new features we've talked about and the old features together all in the same package. And it's going to get you something that will basically work out for you. So at this point I'm going to turn the stage back over to Jean-Pierre. Thanks a lot.
Thank you. So where to find documentation? Well, you can find documentation in two places. Let me start with the second one on that slide, the software distribution document. This does not refer to the distribution script that we talked about today. This is a document that we have that explains how to create packages and how to use PackageMaker. This is actually on our website.
You can go ahead and download it. It's very useful, explains all the flags in the Info.plist. But that's for Panther, for 10.3 packages. We will extend it to include some of the Tiger features, but it's not been updated yet. Now we have a session download, connect.apple.com. If you go to the session 403, you will find something that contains all the examples that we showed you today.
You will find a simple example of file version checking and how it works, some documentation. You will also find a few other examples. You will also find a folder called installer plugins that will contain the plugins that we showed you today and the sources and the project file for Xcode. And you will also find in there a distributions folder which contains the distribution test app. Remember that distributions do not work with the Tiger installer right now.
So you need to use the distribution test app and some of the examples that you were shown today as well. So thank you for coming for this session. We're now going to have a Q&A. And I will see you in a few minutes. Thank you. And I would like to call the people in my group back on stage, including Jonathan Stuecker and Aldo, our installer tech lead.