8

I am writing a class library for Mac OS X and iOS to be released as a Cocoa Framework for OS X and a Static Library for iOS. To simplify matters, I intend to use multiple targets in Xcode. However, the classes on Mac OS X link against Cocoa.h whereas on iOS they link against Foundation.h.

My questions basically are:

  • Could the Mac OS X framework link against Foundation.framework instead? Classes used within the framework are NSString, NSMutableString, and NSMutableArray.
  • Or could I use preprocessor directives within the header files to control framework inclusion, e.g.

    #ifdef MacOSX
        #import <Cocoa/Cocoa.h>
    #else
        #import <Foundation/Foundation.h>
    #endif
    
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
BWHazel
  • 1,474
  • 2
  • 18
  • 31
  • Take a look at this http://stackoverflow.com/questions/3181321/which-conditional-compile-to-use-to-switch-between-mac-and-iphone-specific-code. – detunized Jan 25 '11 at 20:58

4 Answers4

21

You can use these to separate platform dependent code (see TargetConditionals.h):

#ifdef TARGET_OS_IPHONE 
    // iOS
#elif defined TARGET_IPHONE_SIMULATOR
    // iOS Simulator
#elif defined TARGET_OS_MAC
    // Other kinds of Mac OS
#else
    // Unsupported platform
#endif

Here's a useful chart.

detunized
  • 15,059
  • 3
  • 48
  • 64
  • 3
    I did a bit of testing and corrected the code accordingly. Apparently `TARGET_OS_MAC` is defined for iOS as well. Best is really to look into `TargetConditionals.h` and see which macros suit your needs. There's quite a few of them. – detunized Jan 25 '11 at 20:55
  • 1
    I believe now you need to use `#if TARGET_OS_IPHONE`, instead of `#ifdef`. – Vincent Tourraine Oct 07 '13 at 07:52
  • 3
    This answer is wrong. There's a couple problems: First, `TARGET_OS_IPHONE` will always be defined. It's defined as 0 sometimes, but it's still defined. Same with `TARGET_IPHONE_SIMULATOR`. But, also, `TARGET_IPHONE_SIMULATOR` will never be 1 unless `TARGET_OS_IPHONE` is also 1. If you need to check for the iOS simulator specifically, you should do that check first, like: `#if TARGET_IPHONE_SIMULATOR` / `#elif TARGET_OS_IPHONE` / `#elif TARGET_OS_MAC` / `#endif`. – Steven Fisher Dec 06 '13 at 20:20
8

It works like a charm:

#ifdef __APPLE__
  #include "TargetConditionals.h"

  #if TARGET_IPHONE_SIMULATOR  
  // ios simulator

  #elif TARGET_OS_IPHONE
  // ios device

  #elif TARGET_OS_MAC
  // mac os 

  #else
  // Unsupported platform
  #endif
#endif
iuriimoz
  • 951
  • 10
  • 11
2
  • Could the Mac OS X framework link against Foundation.framework instead? Classes used within the framework are NSString, NSMutableString, and NSMutableArray.

Try it and see. If the compile fails, no. If it succeeds, yes.

  • Or could I use preprocessor directives within the header files to control framework inclusion, e.g.

Yes, you can. In fact, I believe that is the only way to do that.

Cajunluke
  • 3,103
  • 28
  • 28
  • Thank you. Thinking about it, Foundation is a framework, therefore I suppose there shouldn't be an issue. I'll give it a go and see! – BWHazel Jan 25 '11 at 22:22
  • Come to think of it, Core Plot does exactly what you want to do. If you have issues, check it out and see what they do. – Cajunluke Jan 25 '11 at 23:00
1

This works perfectly for me:

#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
//iOS 
#else
//Mac
#endif
Tibidabo
  • 21,461
  • 5
  • 90
  • 86