8

I'm attempting to use a library which has a iOS5 and iOS4.3 flavours. The problem I'm having is getting the right version included conditionally, i.e:

for iOS5:

#include ios5stuff.h
@implementation
  // do stuff
@end

For iOS4

#include ios4stuff.h
@implementation
  // do stuff
@end

I can see how to conditionally include stuff within the class's implementation block, but not outside this. Can anyone suggest the best way of doing this?

TimD
  • 8,014
  • 2
  • 24
  • 34
  • Possible duplicate: http://stackoverflow.com/questions/1864114/how-to-detect-iphone-os-version-using-macros – IronMensan Oct 11 '11 at 12:31

3 Answers3

19

You should be able to do this (untested):

#import <Availability.h>

#if defined(__IPHONE_5_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0
#import "my_header_for_io5_and_above.h"
#elif defined(__IPHONE_4_3) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_3
#import "my_header_for_ios4.3.h"
#else
#error Your SDK is too old ! Need at least 4.3.
#endif
elitalon
  • 9,191
  • 10
  • 50
  • 86
DarkDust
  • 90,870
  • 19
  • 190
  • 224
1

If you look at the Foundation headers (NSString, NSData...) there are lots of

#if MAC_OS_X_VERSION_10_6 <= MAC_OS_X_VERSION_MAX_ALLOWED || __IPHONE_4_0  <= __IPHONE_OS_VERSION_MAX_ALLOWED
/* ... */
#endif

There is also a definition for

__IPHONE_OS_VERSION_MIN_REQUIRED
jbat100
  • 16,757
  • 4
  • 45
  • 70
0

You can use this method or the one that DarkDust says and check IOS SDK version when you are compiling, but typically what's nicer is if you handle some of this stuff at runtime since users can update their device and then magically adopt new features or get better OS integration.

There are a couple of ways of doing this. In newer SDKS you should have NS_CLASS_AVAILABLE. However, if you are still supporting older SDKs you may not. But this is objective-c, so luck is on our side:

Class cls = NSClassFromString (@"NSRegularExpression");
if (cls) {
    // Create an instance of the class and use it.
} else {
    // Alternate code path to follow when the
    // class is not available.
}

Basically the way this works is asks the type system if a class is available, if not, it returns null. This is somewhat dangerous if left untested because it is a string and will compile, but you should be able to handle it.

If it's a class that exists in both places, you can test selector availability at runtime like this:

if( [TheAppleClass instancesRespondToSelector:@selector(aMethod:)] ) {
    // invoke the inherited method
    [myInstance aMethod:parameter];
}

reference1 reference2

By doing this you could provide a build that still supports OS4.2 users with a custom tweet sheet, but when they upgrade, they automatically get the OS twitter integration. But, it's still all in a single build you can release when you want without having to wait for 90% of the market to update before you start alienating older OS users.

Community
  • 1
  • 1
slf
  • 22,595
  • 11
  • 77
  • 101
  • 1
    Poster said he needs to import a different header, depending on SDK he links against. So runtime solutions obviously are too late ;-) – DarkDust Oct 11 '11 at 13:20
  • Yeah, I know what he asked for, and yours is a real answer to the question. I'm challenging that need. – slf Oct 11 '11 at 13:47
  • Unfortunately I do need to import different headers - but that's a really useful summary of checking the state of things at runtime, thanks. – TimD Oct 18 '11 at 00:56