Search code examples
iosobjective-cmacrospreprocessor

iOS/Objective-c: How to get a macro that says the version is higher or equal to 13.0 in the .h file?


I would like to have a macro that allows me to check the version or higher than the ios 13. I don't want to use that :

if (@available(iOS 13, *)) {
    // iOS 13 (or newer) ObjC code
} else {
    // iOS 12 or older code
} 

Because the preprocessor will try to compile it and will not be able to do it. What I want is a macro that allows to compile properly without warning or errors message. Something like that:

#ifdef __IPHONE_13_0

But I am not sure that line means 13.0 or higher.

My code in the .h is the following:

#ifdef __AVAILABILITY_INTERNAL__IPHONE_13_0
@property (nonatomic, retain) UIViewController *popoverController;
#else
@property (nonatomic, retain) UIPopoverController *popoverController;
#endif

It doesn't work. How to check in the .h file the version of the ios? I cannot use that as it is in the .h file :

#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

if (SYSTEM_VERSION_LESS_THAN(@"5.0")) {
    // code here
}

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
    // code here
}

What do you think ?

EDIT: How to avoid to get the message for the ipads before a previous version?

enter image description here Thanks in advance.


Solution

  • But you are allowed to use the preprocessor variables when defining your API

    @property (nonatomic, retain) UIViewController *viewController NS_DEPRECATED_IOS(2.0, 13.0);
    @property (nonatomic, retain) UIPopoverController *popoverController API_AVAILABLE(ios(13.0));
    

    same for methods

    -(void)halleluja:(Evil)brain API_AVAILABLE(ios(13.0)) {
        //do evil stuff with brain
    }
    

    do not forget, your Apps targeted system version is meant here.

    You will find plenty of different variations on how to in the documentations of (upper file part)
    #import "Availability.h"
    But you don't need to include it, Xcode does that for you.

    You can also tell your pre-compiler

    #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_13
        // code starting with ios(13.0)
        [self halleluja:nope];
    #else
        // code earlier ios(13.0)
        [self halleluja:papa]; //as defined above should throw a warning
    #endif 
    

    and finally you can ask at runtime

    if ([[[UIDevice currentDevice] systemVersion] isEqualToString:@"13.0"]) {
        // code only on ios(13.0) and only ios(13.0)!
    }
    

    or

    NSString *versionString = [[UIDevice currentDevice] systemVersion];
    if ([versionString floatValue] >= 13.0) {
        // not sexy - but works.
    }