How to get the OS Version String in MAC 10.10 without using gestalt

2.3k Views Asked by At

My objective is to collect the OS Version, release details of MAC 10.10.

I have found a way to collect the version details in MAC 10.10 and as well as from prev. version from the link

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

While I compile it is throwing error at "objc_msgSend_stret", when i search the /usr/include/objc folder itself was not exist in my MAC. i could see only gcc present and all my code was build with it.

Is there any best way to copy the output of

[[NSProcessInfo processInfo], @selector(operatingSystemVersion)] to a struct as "MyOperatingSystemVersion"?

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
}
1

There are 1 best solutions below

2
On BEST ANSWER

I'm guessing that you aren't building this with the 10.10 SDK, otherwise you could simply remove your call to objc_msgSend_stret and call operatingSystemVersion directly.

// Built with 10.10 SDK
if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) {
    NSOperatingSystemVersion version = [[NSProcessInfo processInfo] 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
}

If you're using an earlier SDK, then NSOperatingSystemVersion and -[NSProcessInfo operatingSystemVersion] are both undefined. Since you can't use -[NSProcessInfo operatingSystemVersion] without getting a compiler error, the safer way to call it and get the return value of a non-object type is with NSInvocation. This is still technically risky because you're assigning the return value to a different type of struct (MyOperatingSystemVersion vs. NSOperatingSystemVersion), but you have defined them both the same so it should be ok. I tested this with Xcode 5 / 10.9 SDK and it worked fine.

// Built with 10.9 or earlier SDKs
if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) {
    MyOperatingSystemVersion version;
    NSMethodSignature *methodSignature = [[NSProcessInfo processInfo] methodSignatureForSelector:@selector(operatingSystemVersion)];
    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:methodSignature];
    inv.selector = @selector(operatingSystemVersion);
    [inv invokeWithTarget:[NSProcessInfo processInfo]];
    [inv getReturnValue:&version];
    // 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
}

That should take care of the problem, but the safest thing to do is build with the 10.10 SDK and use the first example.