-
-
Save steipete/6526860 to your computer and use it in GitHub Desktop.
// 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; | |
} |
In order to check which SDK version was used to build a binary, UIKit uses the _UIApplicationLinkedOnOrAfter
function. It is implemented by comparing the major version of UIKit at link time (NSVersionOfLinkTimeLibrary("UIKit") >> 16
) to a value in the __UIKitVersionNumbers
table.
Here is this UIKit version numbers table, built by running otool -L
on UIKit of all these iOS versions (yes I have a huge archive!):
Index | iOS Version | Hexadecimal | Decimal |
0 | 2.0 | 0x0E5 | 229 |
1 | 2.1 | 0x2EB | 747 |
2 | 2.2 | 0x2F0 | 752 |
3 | 2.2.1 | 0x2F1 | 753 |
4 | 3.0 | 0x333 | 819 |
5 | 3.1 | 0x3E8 | 1000 |
6 | 3.2 | 0x44C | 1100 |
7 | 4.0 | 0x4B0 | 1200 |
8 | 4.1 | 0x514 | 1300 |
9 | 4.2.1 | 0x578 | 1400 |
10 | 4.2.6 | 0x582 | 1410 |
11 | 4.3 | 0x5DC | 1500 |
12 | 5.0 | 0x640 | 1600 |
13 | 5.1 | 0x6A4 | 1700 |
14 | 6.0 | 0x944 | 2372 |
15 | 6.1 | 0x94C | 2380 |
16 | 7.0 | 0xB57 | 2903 |
17 | 7.1 | 0xB77 | 2935 |
Weirdly enough, the __UIKitVersionNumbers
contains 0x2EC
instead of 0x2EB
for iPhone OS 2.1. But since nobody cares at all about iPhone OS 2 this should not be a problem.
Awesome thread!
One tiny thing to add:
If kCFCoreFoundationVersionNumber_iOS_7_0 is undefined, use following snippet:
ifndef kCFCoreFoundationVersionNumber_iOS_7_0
define kCFCoreFoundationVersionNumber_iOS_7_0 847.2
endif
Instead of the defining the var I would use the &
... like
if (&kCFCoreFoundationVersionNumber_iOS_7_0 &&
kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_7_0)
{ ...
For anyone googling their way here, 8.0 is 0xCF6.
iOS 9.3: 0xDB8
iOS 10b4: 0xE0C
For iOS 12 (GM), it seems that casting to unsigned integer is now required:
(lldb) p (int32_t)NSVersionOfLinkTimeLibrary("UIKit") >> 16
(int32_t) $4 = -4536
(lldb) p (uint32_t)NSVersionOfLinkTimeLibrary("UIKit") >> 16
(uint32_t) $5 = 61000
-> UIKitVersionNumber_iOS_12_0 = 0xEE48
iOS 15.0 is 0x13CB
(lldb) p (uint32_t)NSVersionOfLinkTimeLibrary("UIKit") >> 16
(uint32_t) $2 = 5067
iOS 15.2 is 0x1455
(lldb) p (uint32_t)NSVersionOfLinkTimeLibrary("UIKit") >> 16
(uint32_t) $1 = 5205
Check the
dyld(3)
man page:They're just whatever number the team for that library uses.