80: Embedded Frameworks Example
Problem: We want to create our own library of pre-compiled code that we can include as part of our applications. We want to be able to continue developing the library without having to re-install it in each application that uses it.
Plugin developers note: These procedures may be used in the context of embedded plugin based applications, i.e. where the plugin files are copied into the application bundle.
This example is a restatement of the example provided in a Quicktime movie by Rentzsch.
The process, as Rentzsch describes it is straightforward but I was unable to derive it from the documentation: Framework Programming Guide.
Brief explanations of some of the factors involved in creating a framework are provided by Jabbering Giraffe: Embedding Cocoa Frameworks and Cocoa is My Girlfriend Cocoa Tutorial: Creating your very own framework
A useful related piece of documentation is the Software Delivery Guide
I have also provides a compact version of this example which lacks the graphics and may be easier to follow.
Use XCode to create a basic framework.
Define the installation path.
Specify the pre-binding Linker flaggs address.
Expose the header file.
Create a New Application.
Add the Framework.
Embed the Framework in the application bundle.
Define Cross Project Target Dependencies so that the app will update its compiled version of the framework as changes are made in the Framework source.
Make changes to the Framework and see them reflected in the application.
i. Create the framework (XCode 3.2.2).
In XCode do File->NewProject->Cocoa framework.
In XCode choose Cocoa Framework
Create an example class (MyClass) with a method that shows it has been called.
In the Farmework create a class and a method
ii. Define the installation path.
In Groups and Files open the Targets, select the Framework and click on the Info button.
Select Groups and Files, Targets, Frameworks, click on Info button
In the Info panel select the Build tab and look for the Installation Directory. Note that in previous versions of XCode this would have been called the Installation Path.
Set Installation Directory to @executable_path
Prior to editing the path will be either:
Set it to: @executable_path/../Frameworks
Notice that in the Rentsch example he sets the Other Linker Flaggs. That is only required for OS X 10.3.9 and earlier (see Table 1 Framework configuration options in the Framework Programming Guide)
iii. Expose the header file and build the Framework.
In the XCode window, with the Framework, set the Role for MyClass.h to public.
Click on the Build button to build it.
Expose the header file
iv. Create the Application and add the Framework.
In XCode create a new Cocoa application. Call it FrameworkApp80.
Start by adding our Framework. Open the Frameworks folder. Control click on Linked Frameworks and choose Add->Existing Frameworks.
Add framework to the application
A list of Mac frameworks appears, click on the Add Other... button.
Click on the Add Other... button
An Open File panel appears. Find the framework folder, find the Build folder, then in The Debug folder choose the framework file.
Choose FrameworkApp_80->Build->Debug->Framework_80.framework (inset)
Add a new Copy Files Build Phase to the application target. It will be used to install the framework in the application bundle.
Add New Copy Build Phase
When the Info panel comes up set the destination to Frameworks.
Set the destination to Frameworks
To specify which files to copy, drag the Framework_80.framework folder from Linked Frameworks to the Copy Files folder.
Specify the files to be copied by dragging them from the Linked Frameworks folder to the Copy Files folder. Inset shows the result.
Build and run. If everything has been processed alright then the Framework will have been copied into the .app package. We can see this by opening up FrameworkApp80->build->Debug->FrameworkApp80.app to show the package contents which should now contain our framework.
Examine the package contents to ensure they contain our framework
Now to make our application use the framework. Add the framework to main.m and call the MyClass printHelloWorld method. Build and run. In the Console you should see the Hello World mesage. And this message was output by the framework.
Use the framework
v. Create a cross project target dependency so XCode will know where to obtain the latest version of our framework.
To create the traget dependency so that the application will always have access to the latest version of the framework we need first make FrameworkApp80 aware of Framework_80. This is done simply by adding the Framework_80.xcodeproj file to the project and then declaring a the application to be directly dependent on the framework.
To do this, do FrameworkApp80 Project->Add to Project. Navigate to the Framework_80 folder and select the Framework_80.xcodeproj file. When the copy panel appears set the Reference Type to Relative to Project.
Project->Add to Project->Framework_80.xcodeproj file
Define the Framework_80.xcodeproj file to be Relative to Project
Select the FrameworkApp80 target, click on Info and under the General tab add the Direct dependency to Framework_80.
Declare a Direct Dependency between the application ond the custom framework
To check that the dependency has been properly defined, add a line to the printHelloWorld method but do not build it. Just save. After having printed Hello the method now prints Bye!!!.
Modify the framework and save but do not build
Run the application which now builds the framework before running