On Feb 14, 2012, at 18:35 , Erik Stainsby wrote: From the reading I've been doing this seems to be the tree I ought to be creating in a single workspace(?) is this:
------------------------------- MyFramework (project) MyApp MyFramework.h MyFramework.m Supporting Files Frameworks Cocoa.framework Other Frameworks Products MyFramework.framework ------------------------------- MyApp (project) MyApp MyAppDelegate.h MyAppDelegate.m MainMenu.xib Supporting Files Frameworks Cocoa.framework Other Frameworks Products MyApp.app -------------------------------
I understand from Chris Hanson that the framework should be built using the user setting: DYLIB_INSTALL_NAME_BASE = @rpath
and the app which will include it should have: LD_RUNPATH_SEARCH_PATHS = @executable_path/../Frameworks
which implies that the framework has to be copied into the Contents/Frameworks folder of the application, presumably as a step in the build of the application. However, any place in the application which I have tried to introduce teh framework causes a choke of some kind. I'm not getting this right and it is getting a bit frustrating.
Your workspace arrangement is basically correct, but you need to do a couple more things:
-- You need to link your app against the framework. You can use the Link Binaries with Libraries build phase for the app target (which is a tab next to the build settings). It has a "+" button at the bottom of the phase, which will give you a dialog from which you can choose the framework. (I think you're supposed to be able to drag MyFramework.framework into the app's Frameworks group, but at one point I couldn't get this to work properly, so I changed to doing it via the build phase. No doubt I was just doing it wrong.) Once this is done, you can drag the MyFramework.framework item into the app's Frameworks group for clarity.
-- You should set the app's Framework Search Paths build setting to the directory containing your framework project. This means that your app can (and should) include framework header files with the #import <MyFramework/SomeHeader.h> syntax. I can't remember whether the linker needs this setting too, when the framework project is in the same workspace, but you at least need it to find the header files.
-- You should go through the header files in your framework project and set their role (in the hideable inspector pane at the right of the Xcode window). Header files that your app wants plug-in developers to see should be marked "public". Header files your app wants to use but doesn't want plug-in developers to see should be marked "private". Header files that are internal to the framework should keep their "project" role. (You can also adjust roles by moving files around in the framework target's Copy Headers build phase. It's sometimes easier here, since you can see all your header files at once.)
However, marking the "private" files won't actually keep them out of the built app, so you have to delete them yourself (if you care). I don't know if there's an easier way, but I use a custom build phase that runs the following script:
cd "$TARGET_BUILD_DIR/$FRAMEWORKS_FOLDER_PATH" rm -rfdv *.framework/Versions/*/PrivateHeaders rm -rfv *.framework/PrivateHeaders
which I believe I stole from a years old web article written by Chris Hanson.
-- You also need (AFAIK) to add a build phase to copy your framework into your app bundle. Otherwise your app won't run outside the Xcode environment.
These last 2 build phases can be marked as "run only when installing". This means they only run when you archive your app, since that's the only build variant that does the so-called installation steps.
When you run your app from within Xcode, it sets up a lot of stuff so that the framework works even if it isn't in the app yet. If you don't realize that Xcode is being very, very clever then things start to seem confusingly magical. :)
Finally, if things go wrong, you really should include the exact text of error messages when you post here, and at what point of which build then appear. Frustrating as this process seems, the key to solving the problems really is in the error messages.
|