From b2a7e116b444b18da0be6efd031b82f00aa9c6ea Mon Sep 17 00:00:00 2001 From: Boris Vidolov Date: Fri, 18 May 2018 15:14:41 -0700 Subject: Allow for building GTMSystemVersion under deployment target of 10.8 and above. - Keep Gestalt APIs till 10.8. - On 10.8 and 10.9 use sysctl and infer the OS version from there. - On 10.10+ use NSProcessInfo. - Added unit test to cover it. --- Foundation/GTMSystemVersion.m | 52 +++++++++++++++++++++++++++++++++++++++ Foundation/GTMSystemVersionTest.m | 26 ++++++++++++++++++++ 2 files changed, 78 insertions(+) (limited to 'Foundation') diff --git a/Foundation/GTMSystemVersion.m b/Foundation/GTMSystemVersion.m index 446766b..6519902 100644 --- a/Foundation/GTMSystemVersion.m +++ b/Foundation/GTMSystemVersion.m @@ -19,6 +19,11 @@ #import "GTMSystemVersion.h" #import +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10 && \ + MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 +#include +#include +#endif #if GTM_MACOS_SDK #import @@ -50,6 +55,7 @@ static NSString *const kSystemVersionPlistPath = @"/System/Library/CoreServices/ // ). // The iPhone doesn't have Gestalt though, so use the plist there. #if GTM_MACOS_SDK + #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8 __Require_noErr(Gestalt(gestaltSystemVersionMajor, &sGTMSystemVersionMajor), failedGestalt); __Require_noErr(Gestalt(gestaltSystemVersionMinor, @@ -61,6 +67,52 @@ static NSString *const kSystemVersionPlistPath = @"/System/Library/CoreServices/ failedGestalt: ; + #elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10 + // Gestalt() is deprected in 10.8, and the recommended replacement is sysctl. + // https://developer.apple.com/library/mac/releasenotes/General/CarbonCoreDeprecations/index.html#//apple_ref/doc/uid/TP40012224-CH1-SW16 + // We will use the Darwin version to extract the OS version. + const int kBufferSize = 128; + char buffer[kBufferSize]; + size_t bufferSize = kBufferSize; + int ctl_name[] = {CTL_KERN, KERN_OSRELEASE}; + int result = sysctl(ctl_name, 2, buffer, &bufferSize, NULL, 0); + _GTMDevAssert(result == 0, + @"sysctl failed to rertieve the OS version. Error: %d", + errno); + if (result != 0) { + return; + } + buffer[kBufferSize - 1] = 0; // Paranoid. + + // The buffer now contains a string of the form XX.YY.ZZ, where + // XX is the major kernel version component and YY is the +1 fixlevel + // version of the OS. + SInt32 rawMinor; + SInt32 rawBugfix; + int numScanned = sscanf(buffer, "%d.%d", &rawMinor, &rawBugfix); + _GTMDevAssert(numScanned >= 1, + @"sysctl failed to parse the OS version: %s", + buffer); + if (numScanned < 1) { + return; + } + _GTMDevAssert(rawMinor > 4, @"Unexpected raw version: %s", buffer); + if (rawMinor <= 4) { + return; + } + sGTMSystemVersionMajor = 10; + sGTMSystemVersionMinor = rawMinor - 4; + // Note that Beta versions of the OS may have the bugfix missing or set to 0 + if (numScanned > 1 && rawBugfix > 0) { + sGTMSystemVersionBugFix = rawBugfix - 1; + } + #else // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 + NSOperatingSystemVersion osVersion = + [[NSProcessInfo processInfo] operatingSystemVersion]; + sGTMSystemVersionMajor = (SInt32)osVersion.majorVersion; + sGTMSystemVersionMinor = (SInt32)osVersion.minorVersion; + sGTMSystemVersionBugFix = (SInt32)osVersion.patchVersion; + #endif #else // GTM_MACOS_SDK NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *version = nil; diff --git a/Foundation/GTMSystemVersionTest.m b/Foundation/GTMSystemVersionTest.m index b881233..42a1b77 100644 --- a/Foundation/GTMSystemVersionTest.m +++ b/Foundation/GTMSystemVersionTest.m @@ -90,4 +90,30 @@ XCTAssertTrue([GTMSystemVersion isBuildLessThan:largeVersion]); } + +#ifdef GTM_MACOS_SDK +- (void)testMacOSVersion { + SInt32 major = -1; + SInt32 minor = -1; + SInt32 bugfix = -1; + + [GTMSystemVersion getMajor:&major minor:&minor bugFix:&bugfix]; + NSDictionary *versionPlistContents = + [NSDictionary dictionaryWithContentsOfFile: + @"/System/Library/CoreServices/SystemVersion.plist"]; + XCTAssertNotNil(versionPlistContents); + NSString *version = + [versionPlistContents objectForKey:@"ProductVersion"]; + XCTAssertNotNil(version); + NSArray *pieces = [version componentsSeparatedByString:@"."]; + XCTAssertTrue([pieces count] > 2); + XCTAssertEqual(major, (SInt32)[[pieces objectAtIndex:0] integerValue]); + XCTAssertEqual(minor, [[pieces objectAtIndex:1] integerValue]); + if ([pieces count] > 2) { + XCTAssertEqual(bugfix, [[pieces objectAtIndex:2] integerValue]); + } else { + XCTAssertEqual(bugfix, 0, @"possible beta OS"); + } +} +#endif @end -- cgit v1.2.3