I want to be able to have two classes that are responsible to respond to selectors differently depending if the platform is iOS or OSX.
However, I want to have code that uses only one class, and I want to avoid repeating #ifdefs.
Ideally I would want to have 3 classes:
iOSSpecificClass
and OSXSpecificClass
both extend UniversalClass.
All calls would be done to UniversalClass, and that class is responsible to call the respective methods of iOSSpecificClass
and OSXSpecificClass
.
There are two solutions that I came up with:
@interface UniversalClass : NSObject
+ (void) universalMethod;
@end
@implementation UniversalClass
+(id)forwardingTargetForSelector:(SEL)aSelector {
#if TARGET_OS_IPHONE
return [iOSSpecificClass class];
#else
return [OSXSpecificClass class];
#endif
}
@end
The problem with this approach is that UniversalClass
promises something in the .h that can or cannot deliver. The warnings also tell us that. Grr. Warnings.
The second approach would be like this:
@implementation UniversalClass
+ (Class)correctClass {
Class aClass = Nil;
#if TARGET_OS_IPHONE
aClass = [iOSSpecificClass class];
#else
aClass = [OSXSpecificClass class];
#endif
return aClass;
}
+ (void)universalMethod {
Class masterClass = [UniversalClass correctClass];
[masterClass universalMethod];
}
@end
The problem with this approach is that I have to perform changes for every method I add and I feel that I am kinda repeating myself without needing.
What are the edge cases I have to pay attention to in both solutions? Is there any better solution than those?
One option is to have a common header file and two different implementations for two targets (one for OSX and another for iOS) that both import and implement the header methods.
Something like this: