I have a Constants.h
file in my app, where I #define
app-wide things for easy access later. I'm having a hard time, though, #define
ing based on iOS version. Here's what I've tried:
#ifdef __IPHONE_7_0
#define kHamburgerImage [UIImage imageNamed:@"reveal_menu_icon_portrait_ios7.png"];
#else
#define kHamburgerImage [UIImage imageNamed:@"reveal_menu_icon_portrait.png"];
#endif
Just because it says iOS 7 in there doesn't mean this is under NDA, O closers!
Which works fine - for iOS 7. When I run my app on iOS 6, however, the #define
is still the iOS 7 one - it seems as though the #ifdef
is never taken into account.
What can I do to fix this?
Instead of using compile-time checks, you need runtime checks. This means you can't use #define
. I suggest using a static variable that is initialized at runtime based on the version of iOS. Below is an example if you only need the value in a single file.
Some .m file:
static UIImage *kHamburgerImage = nil;
+ (void)initialize {
// This assumes you only support iOS 6 and later - adjust as needed
if ([[UIDevice currentDevice].systemVersion hasPrefix:@"6"]) {
kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait.png"];
} else {
kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait_ios7.png"];
}
}
Edit: Since these need to be globals, you should do this:
Constants.h:
extern UIImage *kHamburgerImage;
@interface Constants
@end
Constants.m:
UIImage *kHamburgerImage = nil;
@implementation Constants
+ (void)initialize {
// This assumes you only support iOS 6 and later - adjust as needed
if ([[UIDevice currentDevice].systemVersion hasPrefix:@"6"]) {
kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait.png"];
} else {
kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait_ios7.png"];
}
}
@end
But this suffers from a problem. Unless you take specific steps, accessing these globals could result in nil
pointers. They only get initialized if the class is actually referenced. I suggest that as the first line of your application:didFinishLaunchingWithOptions:
you do:
[Constants class];
This ensures the initializer is called and the constants are setup before you use them anywhere else in your code.