views:

409

answers:

6

I have a project that targets both Mac OS X 10.4 and 10.5, where 10.5 is the base SDK.

Some methods like -[NSString stringByReplacingOccurrencesOfString:withString] are unavailable in 10.4. I could just implement the functionality by hand. Another option would be to implement the method as a category, but that would mess with the 10.5 implementation and that's something I'd like to avoid.

So how do I implement such methods in 10.4 without messing up 10.5 and in such a way that I can take out the implementation easily when I decide to stop supporting 10.4?

+2  A: 

I think you have to use +load and +initialize to load a method at runtime if the method doesn't already exists.

Georg
What's the best place to put it for classes that I don't own, like NSString?
sjmulder
+load, this method is special and is called if it's implemented in the category. This means you can have more than 1 +load method.
Georg
In that case this is the answer, thank you :)
sjmulder
A: 

How about using a C preprocessor macro to insert the relevant methods if it's being built for 10.4? Maybe try doing something like this in a category, so those methods which don't exist on 10.4 are only included if it's being built for 10.4?

#if defined(MAC_OS_X_VERSION_10_4) && MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
// Put your implementations of the methods here
#endif
Matt Ball
I'm doing one build with 10.5 as base SDK and 10.4 as deployment target. So it's always built with the 10.5 SDK but it runs on 10.4 (as long as I don't actually call new APIs when on Tiger).
sjmulder
I think you should build it against the 10.4 SDK for the older versions of Mac OS X, if that's not what happens automatically.
Georg
No, I want to use select 10.5 features if available.
sjmulder
A: 

Do you need to support 10.4? If you're using 10.5 only methods in core parts of your app then it might be time to consider going 10.5 only.

Anyway, with the specific example given above, I suggest moving away from that and making a mutable copy of your string so you can use the similar method on NSMutableString which does work in 10.4

Martin Pilkington
+2  A: 
if ([myString respondsToSelector: @selector(stringByReplacingOccurrencesOfString:withString:)])
{
  // 10.5 implementation
}
else
{
  // 10.4 implementation
}
Graham Lee
+2  A: 

Use a category, but put a tag on the method name; for example, stringByReplacingOccurrencesOfString_TigerCompatible:. In the implementation, call either Leopard's implementation or your own.

When you go Leopard-only, do a project search for “TigerCompatible”, then burninate all of those methods and un-tag all of their call sites.

Peter Hosey
+1  A: 

Put all the missing implementation in categories in a bundle which is loaded on startup in main() if running under Tiger.

Christopher Lloyd
Hey that's a pretty simple but neat idea. I might actually go for that.
sjmulder