views:

403

answers:

5

Hey folks,

I've got a client<=>server app I'm building for Mac OS X, using Objective-c/Cocoa and xCode. I've created a different project for both the apps I have, and I'm wondering the best way to share classes between them. There are several classes I've made that would be useful to both. This far I've been copying them around, but I feel like this isn't the best solution.

How do I share classes effectively? Should I redo it as 1 project and just have two build targets? How do I do this?

Any other info?

Thanks.

+2  A: 

The best way is to create a separate framework containing the shared classes. This can be compiled up once and linked into both application projects.

See Apple's doc on what are Frameworks.

Mark
+1  A: 

The fastest solution is to add only references of the .h and .m files to one of the projects. Just uncheck the "copy"-checkbox in the "add existing files"-dialog in xcode. Keep in mind the you might also need to copy the referenced files if you move/share your project.

Felix
Would this play nicely with source control? I'm guessing that the frameworks solution would work more naturally with CVS and friends.
Spina
A: 

I found a nice article on this topic here: http://www.clintharris.net/2009/iphone-app-shared-libraries/ This answers my question which is specifically about multiple iPhone apps sharing code. It doesn't mention frameworks (above) so I can't say if their suggestion (xcode project references) compares favorably to the frameworks solution.

Spina
The situation is very different on the iPhone with its filesystem and shared library restrictions.
Nicholas Riley
+2  A: 

A very good way to do it is to put the shared code into SCM system and include it into each project you want it in. This way every project can share the code, you can edit it anywhere and just check the changes back into source control when you're feeling good about it — and then all the other projects benefit from your work.

This has big advantages over other ways of doing it IMO:

vs. frameworks: Packaging code into a framework is pretty annoying, and bundle-private frameworks take an unreasonably long time to load — especially just to get a few classes into your app. Wil Shipley of Omni Group (at the time) once found that the frameworks the company included in all their apps were adding several seconds to the start time of each app. Packaging private classes in a framework can also encourage more coupling than is strictly necessary — it's really tempting just to make One True Framework where all your shared classes reside, so you start assuming this code will always live together. and it becomes inseparable. Basically, frameworks are a hammer and this problem is a screw.

vs. just including files: Hopefully you'll put your app into an SCM at some point anyway, and simply including the files in-place creates a problem because they'll be missing from SCM. Copying the files into each project introduces the opposite problem — each project will include its own version of the files and you'll have to manually propagate any useful changes.

Chuck
+2  A: 

If you have two or more products that are going to share a good amount of common code, like a suite of products, you might want to consider creating just a single xcode project, and then add a different target for each product that will be built from both shared and product-specific code. With a lot of shared code, a client/server pair of products would possibly be great candidates for going this way.

Boiled-down, the basic deal is that for each target in your xcode project that you want to build, you specify which files should be used to build it: source files, art, xibs, and so on. This way, for example, you can setup your client product to be built using files A,B,C,D,E,F, and your server product to be built using files A,F,X,Y,Z.

I really like having every related product living under a single xcode project "roof", because you wont have to jump around xcode projects, and it really simplifies SCM management for the shared files.

Here's a link to Apple's docs on this: http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/XcodeBuildSystem/100-Targets/bs_targets.html

Update: there's a little bit of extra hassle involved when it comes to configuring target-specific header files in xcode (it's always something...right?!); for example, use "myHeaderA.h" for this target and "myHeaderB.h" for that target. Here's a great post that shares how to do it: http://stackoverflow.com/questions/2596695/controlling-which-project-header-file-xcode-will-include. Caution: after you set things up this way, xcode no longer knows any paths to search for any of your target header files, so you have to set them up manually. To do this, right-click Get Info on your target, select Build category, then add your paths via the "Header Search Paths" setting. The paths are searched in the order that you enter them.

JX2