« Frameworks Within The App Bundle
You might have come across several third-party frameworks such as the Omni frameworks or perhaps you wrote your own for easy code reuse across several applications. If you use a framework like that in your application, you probably don't want your users to have to install it separately in /Library/Frameworks just to run your app. Trust me, they will not appreciate it and it most certainly isn't the Mac way of doing things. A much better alternative is to simply include the relevant frameworks in your application's bundle. That way you can avoid having to make an installer and let your users comfortably drag your application to their desired location.
Figure 1: OmniWeb is an example of an application that makes heavy use of frameworks, all of which are included within its own app bundle. (Go have a look inside OmniWeb.app/Contents/Frameworks to see for yourself.)
// Framework Settings
First off, we need to make some changes in your framework's build settings. Open your framework project file in Project Builder and switch to the "Targets" tab in the left-hand pane. Select the target from the resulting list on the left to edit its settings. On the right, you'll see several tabs for the different settings. Click on the "Build Settings" tab and scroll down to the "Installation Location" heading. As you can see in Figure 2, we need to change the path field to @executable_path/../Frameworks. This lets the framework know that it will be placed inside an application bundle. (Note that in reality the executable is located in MyApp.app/Contents/MacOS/MyApp, so @executable_path/../Frameworks translates into MyApp.app/Contents/Frameworks.)
Now, continue to scroll down to "Linker Settings." Make sure the "Prebind" checkbox is selected, as this will enable your application to launch faster. To make sure that prebinding actually works, we'll need to change the preferred address of our framework. By default, it's set to 0x00000000, which means it will overlap with the application you want to use it with, since all executables start at that address. To avoid this problem, you need to add a linker flag called -seg1addr my_address_here. In place of my_address_here, you need to specify an address in the range of 0x00000000 to 0x3FFFFFFF, as well as anything above 0x900000000 (the remaining addresses are reserved by Apple). Obviously using 0x00000000 would be pointless, so you should try something like -seg1addr 0x10000000 or above.
Well, that's it for this part. Don't forget to build the framework when you're finished so that we can use it in the next part of this article. I also recommend you take a look at the notes about prebinding over on Apple's developer site if you want to know more about it.
// Application Settings
So, now that we have the framework built the right way, you can add it to your application. Add it the same way you would add any of the Apple frameworks (using the "Add Frameworks..." item located in the "Project" menu). Unfortunately, that isn't the end of it yet. We need to have Project Builder automatically copy our framework into the application bundle when it's built (more specifically, we want it placed in the MyApplicationHere.app/Frameworks directory). Luckily, this isn't all that hard to do, since Project Builder provides a very handy "Copy Files Build Phase." This will do is exactly as the name implies: copy files to whatever location you specify.
Edit the target settings of your application (the same way we did above with the framework) and click the "Files & Build Phases" tab. Scroll down to the "Frameworks & Libraries" section. There you should see the framework we added earlier, among others. Select that framework, go up to the "Project" menu, and navigate your way down to the "New Build Phase" submenu. Yep, you guessed correctly, you need choose "New Copy Files Build Phase" from that submenu.
In the resulting "Copy Files" section, choose "Frameworks" from the "Where:" pop-up menu. The last thing we need to do is add the actual framework to the "Files:" list. Click the "Files" tab on the left-hand pane of the project window (to get back to your list of project files) and then proceed to drag the MyFramework.framework file (or whatever your framework is called) to the "Files:" list on the right.
After you're done with all that, go ahead and build your app... boom! You should now be able to use any of the classes in your framework.
Well, there's not much left to talk about. Go out and start using the Omni frameworks, roll your own frameworks, or just have fun playing around with this stuff! As a final note, I'd like to thank Kurt Revis for telling me how to make my framework cooperate properly with prebinding and not produce pesky linker warnings everytime I build my app. Like always, if there are any questions, comments, or corrections, feel free to contact me.