I’ve never written an installer with Apple’s PackageMaker. Never had a need to.
However, the day job has recently required me to write a few custom plugins to customize how some installers work.
I was amazed at how easy it was. The InstallerPlugins.framework is very simple and well-constructed. Sure you can’t do everything you need with it, but you can do most and then write scripts and other things to customize it to your heart’s content.
The thing that gets me? There’s almost no documentation on it. Apple provides the InstallerPluginSample code, and really in a lot of ways between that and reading the InstallerPlugins.framework headers, that’s about all you need. It’s that simple and well-written of an SDK.
Still, some things came up while I was working that I couldn’t find an answer to. For instance, I was instructed to create a “display license” panel that replicated the stock panel the installer provided but had a few customizations. The trouble with this? Anything outside of the content panel I couldn’t replicate, such as the “Print” and “Save” buttons. I was pointed to this resource and specifically this FAQ:
[Q] Can I add Print… and Save… buttons similar to the ones used in the default License pane?
- You can do it through an undocumented and private method:
1 Open the nib of your plugin project in Interface Builder. 2 Add a custom view to the nib file. 3 Add Print… and Save… buttons to this custom view. 4 Create outlets in your controller class for this custom view and buttons and make the appropriate connections in Interface Builder. 5 Add 2 methods in your controller class to be called from the 2 buttons and connect the buttons to these methods in Interface Builder. 6 Add the - (id) bottomContentView;method to your controller class and make it return the reference to your custom view.
IMHO, using an undocumented and private method is bad and just asking for breakage and trouble down the line. But, some people are willing to live with that so tread accordingly.
Stéphane Sudre also provides this HOWTO on using PackageMaker. By the screenshots and some text I can see it’s old, so I don’t know how relevant it is to day’s PackageMaker. But there you go.