TimD
TimD

Reputation: 8522

Conditionally including headers depending on iOS version

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?

Upvotes: 8

Views: 7339

Answers (3)

DarkDust
DarkDust

Reputation: 92335

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

Upvotes: 19

slf
slf

Reputation: 22767

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.

Upvotes: 0

jbat100
jbat100

Reputation: 16827

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

Upvotes: 1

Related Questions