// Taken from http://PSPDFKit.com. This snippet is under public domain. | |
#define UIKitVersionNumber_iOS_7_0 0xB57 | |
BOOL PSPDFIsUIKitFlatMode(void) { | |
static BOOL isUIKitFlatMode = NO; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
// We get the modern UIKit if system is running >= iOS 7 and we were linked with >= SDK 7. | |
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_7_0) { | |
isUIKitFlatMode = (NSVersionOfLinkTimeLibrary("UIKit") >> 16) >= UIKitVersionNumber_iOS_7_0; | |
} | |
}); | |
return isUIKitFlatMode; | |
} |
This comment has been minimized.
This comment has been minimized.
@manide I've needed a solution that can detect this at runtime, since it's for http://pspdfkit.com and the binary is precompiled with Xcode 5 and might end up in an app built with Xcode 4 or 5 - and I didn't want to make a separate binary just for that. If you have full control over your compile environment, your solution is the easier one. |
This comment has been minimized.
This comment has been minimized.
Here's a different variant that most certainly will not pass App Store review, but it's interesting nonetheless: https://gist.github.com/zwaldowski/6526790 |
This comment has been minimized.
This comment has been minimized.
If kCFCoreFoundationVersionNumber_iOS_7_0 is undefined, use following snippet: ifndef kCFCoreFoundationVersionNumber_iOS_7_0define kCFCoreFoundationVersionNumber_iOS_7_0 847.2endif |
This comment has been minimized.
This comment has been minimized.
Is there a downside to just making a new UIWindow in all cases? It's not that much overhead is it? |
This comment has been minimized.
This comment has been minimized.
Would it be simpler to use something like this?
Then you don't have to worry about checking the key window or using the temporary window. |
This comment has been minimized.
This comment has been minimized.
@jnjosh UIWindow will always respond to tintColor on iOS 7, even in legacy mode. @khakionion This is only a fallback and only created if we don't yet have a window, and instantly destroyed afterwards. Wasn't an issue in my test, and no performance penalty either. But it's not pretty, I agree. |
This comment has been minimized.
This comment has been minimized.
How about [[NSBundle mainBundle] objectForInfoDictionaryKey:@"DTSDKName"] ? Xcode injects that key into app's Info.plist during compilation, and it contains the name of Base SDK (e.g. "iphoneos6.1" or "iphonesimulator6.1"). |
This comment has been minimized.
This comment has been minimized.
Looks like this doesn't work anymore as of iOS 7.1b2. I've updated the code for a new way that works. |
This comment has been minimized.
This comment has been minimized.
NSVersionOfLinkTimeLibrary seems to be the most stable solution. Are those version numbers defined somewhere, or should I just use them as magic constants? |
This comment has been minimized.
This comment has been minimized.
Check the
They're just whatever number the team for that library uses. |
This comment has been minimized.
This comment has been minimized.
In order to check which SDK version was used to build a binary, UIKit uses the Here is this UIKit version numbers table, built by running
Weirdly enough, the |
This comment has been minimized.
This comment has been minimized.
Awesome thread! One tiny thing to add:
Instead of the defining the var I would use the
|
This comment has been minimized.
This comment has been minimized.
For anyone googling their way here, 8.0 is 0xCF6. |
This comment has been minimized.
This comment has been minimized.
iOS 9.3: 0xDB8 |
This comment has been minimized.
This comment has been minimized.
For iOS 12 (GM), it seems that casting to unsigned integer is now required:
-> UIKitVersionNumber_iOS_12_0 = 0xEE48 |
This comment has been minimized.
Does this work, too?
static BOOL UIKitIsFlatMode() {
if defined(__IPHONE_7_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0)
else
endif
}