How do I determine the OS version at runtime in OS X or iOS (without using Gestalt)?

The Gestalt() function located in CarbonCore/OSUtils.h has been deprecated as of OS X 10.8 Mountain Lion.

I often use this function to test the version of the OS X operating system at runtime (see the toy example below).

  • How do I get the currently connected network interface name using Cocoa or Foundation?
  • Where can I find a good tutorial on iPhone/Objective-C multithreading?
  • Moving to another view controller in iOS on Button Click
  • How does NSDocumentController slot into my document based app?
  • NSTextField like safari address bar
  • Get ALL views and subview of NSWindow
  • What other API could be used to check the OS X operating system version at runtime in a Cocoa application?

    int main() {
        SInt32 versMaj, versMin, versBugFix;
        Gestalt(gestaltSystemVersionMajor, &versMaj);
        Gestalt(gestaltSystemVersionMinor, &versMin);
        Gestalt(gestaltSystemVersionBugFix, &versBugFix);
    
        printf("OS X Version: %d.%d.%d\n", versMaj, versMin, versBugFix);
    }
    

    11 Solutions Collect From Internet About “How do I determine the OS version at runtime in OS X or iOS (without using Gestalt)?”

    On OS X 10.10 (and iOS 8.0), you can use [[NSProcessInfo processInfo] operatingSystemVersion] which returns a NSOperatingSystemVersion struct, defined as

    typedef struct {
        NSInteger majorVersion;
        NSInteger minorVersion;
        NSInteger patchVersion;
    } NSOperatingSystemVersion;
    

    There is also a method in NSProcessInfo that will do the comparison for you:

    - (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version
    

    Beware, although documented to be available in OS X 10.10 and later, both operatingSystemVersion and isOperatingSystemAtLeastVersion: exist on OS X 10.9 (probably 10.9.2) and work as expected. It means that you must not test if NSProcessInfo responds to these selectors to check if you are running on OS X 10.9 or 10.10.

    On iOS, these methods are effectively only available since iOS 8.0.

    There is the NSAppKitVersionNumber value which you can use to check the various versions of AppKit, although they don’t correspond exactly to OS versions

    if (NSAppKitVersionNumber <= NSAppKitVersionNumber10_7_2) {
        NSLog (@"We are not running on Mountain Lion");
    }
    

    On the command line:

    $ sysctl kern.osrelease
    kern.osrelease: 12.0.0
    $ sysctl kern.osversion
    kern.osversion: 12A269
    

    Programmatically:

    #include <errno.h>
    #include <sys/sysctl.h>
    
    char str[256];
    size_t size = sizeof(str);
    int ret = sysctlbyname("kern.osrelease", str, &size, NULL, 0);
    

    Darwin version to OS X release:

    16.x.x  macOS 10.12.x Sierra
    15.x.x  OS X  10.11.x El Capitan
    14.x.x  OS X  10.10.x Yosemite
    13.x.x  OS X  10.9.x  Mavericks
    12.x.x  OS X  10.8.x  Mountain Lion
    11.x.x  OS X  10.7.x  Lion
    10.x.x  OS X  10.6.x  Snow Leopard
     9.x.x  OS X  10.5.x  Leopard
     8.x.x  OS X  10.4.x  Tiger
     7.x.x  OS X  10.3.x  Panther
     6.x.x  OS X  10.2.x  Jaguar
     5.x    OS X  10.1.x  Puma
    

    There is a cocoa API. You can get an os X version string from the class NSProcessInfo.

    The code to get the operating System Version String is below..

    NSString * operatingSystemVersionString = [[NSProcessInfo processInfo] operatingSystemVersionString];
    
    NSLog(@"operatingSystemVersionString => %@" , operatingSystemVersionString);
    

    // ===>> Version 10.8.2 (Build 12C2034) result value

    It isn’t deprecated.

    There is also kCFCoreFoundationVersionNumber which can be used if you only need to check for a minimum version to support. This has the advantage that it works going back to 10.1 and can be done in C, C++, and Objective-C.

    For example to check for 10.10 or greater:

    #include <CoreFoundation/CoreFoundation.h>
    if (floor(kCFCoreFoundationVersionNumber) > kCFCoreFoundationVersionNumber10_9) {
        printf("On 10.10 or greater.");
    }
    

    You will need to link with the CoreFoundation (or Foundation) framework.

    It also works in Swift in the exact same way. Here’s another example:

    import Foundation
    if floor(kCFCoreFoundationVersionNumber) > kCFCoreFoundationVersionNumber10_8 {
        println("On 10.9 or greater.")
    } else if floor(kCFCoreFoundationVersionNumber) > kCFCoreFoundationVersionNumber10_9 {
        println("On 10.10 or greater.")
    }
    

    You can easily get the major, minor, patch version of the Operating System using NSOperatingSystemVersion

    NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
    
    NSString* major = [NSString stringWithFormat:@"%d", version.majorVersion];
    
    
    NSString* minor = [NSString stringWithFormat:@"%d", version.minorVersion];
    
    
    NSString* patch = [NSString stringWithFormat:@"%d", version.patchVersion];
    

    Or, to put it more simply, here is the code:

    NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"];
    NSString *productVersion = [version objectForKey:@"ProductVersion"];
    NSLog (@"productVersion =========== %@", productVersion);
    

    I hope this helps someone.

    There’s uname(3):

    The uname() function stores nul-terminated strings of information identifying the current system into the structure referenced by name.

    The utsname structure is defined in the <sys/utsname.h> header file, and
    contains the following members:

    • sysname – Name of the operating system implementation.
    • nodename – Network name of this machine.
    • release – Release level of the operating system.
    • version – Version level of the operating system.
    • machine – Machine hardware platform.

    If you have an app that needs to run on 10.10 as well as prior versions, here’s a solution:

    typedef struct {
            NSInteger majorVersion;
            NSInteger minorVersion;
            NSInteger patchVersion;
    } MyOperatingSystemVersion;
    
    if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) {
        MyOperatingSystemVersion version = ((MyOperatingSystemVersion(*)(id, SEL))objc_msgSend_stret)([NSProcessInfo processInfo], @selector(operatingSystemVersion));
        // do whatever you want with the version struct here
    }
    else {
        UInt32 systemVersion = 0;
        OSStatus err = Gestalt(gestaltSystemVersion, (SInt32 *) &systemVersion);
        // do whatever you want with the systemVersion as before
    }
    

    Note that even 10.9 seems to respond to the operatingSystemVersion selector, so I think it just was a private API in 10.9 (but still works).

    This works on all versions of OS X and doesn’t rely on string parsing or file I/O.

    This is what I use:

    NSInteger osxVersion;
    if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_6) {
        //10.6.x or earlier systems
        osxVersion = 106;
        NSLog(@"Mac OSX Snow Leopard");
    } else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_7) {
        /* On a 10.7 - 10.7.x system */
        osxVersion = 107;
        NSLog(@"Mac OSX Lion");
    } else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_8) {
        /* On a 10.8 - 10.8.x system */
        osxVersion = 108;
        NSLog(@"Mac OSX Moutain Lion");
    } else {
        /* 10.9 or later system */
        osxVersion = 109;
        NSLog(@"Mac OSX: Mavericks or Later");
    }
    

    It is recommended in AppKit Release Notes

    Reading /System/Library/CoreServices/SystemVersion.plist is not possible if the app is sandboxed

    This is actually a compilation of answers above, with some further guiding to the developer in need.

    OS-X provides its version in runtime in several ways. Each way fits better to specific development scenario. I’ll try to summarise them all, and hope that others will complete my answer if I forgot something.

    First, the comprehensive list of ways to obtain the OS version.

    1. The uname command-line tool and function provides the unix (darwin) version of the OS. Although this is not the marketing version of the OS, it is aligned with it uniquely, so you can deduce the OS-X marketing version from it.
    2. sysctl kern.osrelease command line (or sysctlbyname("kern.osrelease", str, &size, NULL, 0) function) will provide the same information as uname, marginally easier to parse.
    3. Gestalt(gestaltSystemVersionMajor) (with its “Minor” and BugFix” variants is the oldest (pre-Carbon!) API to get the marketing OS version, still supported by long deprecated. Available in C from the CoreServices framework, but not recommended.
    4. NSAppKitVersionNumber is a float constant of the AppKit framework, that will provide the OS-X Appkit version (aligned with the OS version), available to all applications which link against AppKit. It also provides a comprehensive enumeration of all possible versions (e.g. NSAppKitVersionNumber10_7_2)
    5. kCFCoreFoundationVersionNumber is a CoreFoundation framework float constant, identical to the Appkit counterpart, available to all apps linked against CoreFoundation, in both C, Obj-C and Swift. It, too provides a comprehensive enumeration over all OS X released versions (e.g. kCFCoreFoundationVersionNumber10_9)
    6. [[NSProcessInfo processInfo] operatingSystemVersionString]; is a Cocoa API available in Obj-C to both OS-X and iOS applications.
    7. There is a resource .plist in /System/Library/CoreServices/SystemVersion.plist which among other things, contains the OS version in the “ProductVersion” key. NSProcessInfo reads its information from this file, but you can do this directly using your PList-reading API of choice.

    For more details on each option – please consult the answers above. There’s plenty of information there!