Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating an iOS/OS X cross-platform class

I read a lot of questions about creating a cross-platform library for these 2 systems. Every answer points to static library as the solution.

I don't want to end up with a static library, I'd like to create a class with methods for iOS and their counterpart for OS X.

-(void)createColor:(NSColor*);
-(void)createColor:(UIColor*);

The first problem that I have is that I can't find a way to use classes that are available only in a specific system. So for example, how could I manage a function that works with UIColor in iOS and with NSColor in OS X?

If I create a project for iOS, when I look into Foundation.h I can't find NSColor.h in the headers list.

I thought to use the TARGET_OS_MAC and TARGET_OS_IPHONE definitions to make a distinction between the two systems... I'm on the right way?

EDIT to add more info:

At the moment I have 2 targets: an iOSTestApp and OSxTestApp. For these targets I have included the needed frameworks depending on the system.

Using TARGET_OS_MAC and TARGET_OS_IPHONE works only when I select the OSXTestApp as active target. When I select the iOSAppTest, Xcode returns errors for OS X data type (i.e. NSColor)

Here an example of the code that produces these errors:

#if TARGET_OS_MAC
-(void)createColor:(NSColor*)color;    

#elif TARGET_OS_IPHONE
-(void)createColor:(UIColor*)color;

#endif

While if I invert the definitions it works ... Here an example of the code that produces these errors:

#if TARGET_OS_IPHONE
-(void)createColor:(UIColor*)color;

#elif TARGET_OS_MAC
-(void)createColor:(NSColor*)color;

#endif
like image 292
MatterGoal Avatar asked Mar 10 '13 14:03

MatterGoal


3 Answers

The problems you're seeing arise from the fact that TARGET_OS_IPHONE is defined as a variant of TARGET_OS_MAC. (In other words, TARGET_OS_IPHONE is a more-specific case of TARGET_OS_MAC. Or TARGET_OS_MAC is to a rectangle as TARGET_OS_IPHONE is to a square).

So the following code errors out when compiling for iOS because iOS would match both of those conditions, but NSColor is not defined for iOS.

#if TARGET_OS_MAC
-(void)createColor:(NSColor*)color;    

#elif TARGET_OS_IPHONE
-(void)createColor:(UIColor*)color;

#endif

The following code works properly for both because for iOS, it matches the first case, and for Mac OS X, it doesn't match the first but does match the second.

#if TARGET_OS_IPHONE
-(void)createColor:(UIColor*)color;

#elif TARGET_OS_MAC
-(void)createColor:(NSColor*)color;

#endif
like image 53
NSGod Avatar answered Nov 14 '22 19:11

NSGod


When it comes to UIColor/NSColor, I handle it like this:

#if TARGET_OS_IPHONE
#define ImageClassName UIImage
#else
#define ImageClassName NSImage
#endif

Then, in header files, and if you're just passing instances around, you can just use e.g. ImageClassName *.

Repeat the #if block in your code when you need to use the UIColor/NSColor APIs.

like image 5
paulmelnikow Avatar answered Nov 14 '22 19:11

paulmelnikow


the two defines you talk about are set to 1 or 0 depending on what you compile for! (at compilation time)

so you are on the right track here I guess

e.g.

#if TARGET_OS_IPHONE
#import <CoreText/CoreText.h>
#elif TARGET_OS_MAC
#import <ApplicationServices/ApplicationServices.h>
#endif
like image 4
Daij-Djan Avatar answered Nov 14 '22 19:11

Daij-Djan