如何在OS X或iOS(不使用格式塔)运行时确定操作系统版本?
位于CarbonCore/OSUtils.h
的Gestalt()函数在OS X 10.8 Mountain Lion中已被弃用。
我经常使用这个函数在运行时testingOS X操作系统的版本(参见下面的玩具例子)。
在Cocoa应用程序中,可以使用其他什么API来检查运行时的OS X操作系统版本?
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); }
在OS X 10.10(和iOS 8.0)上,可以使用[[NSProcessInfo processInfo] operatingSystemVersion]
,它返回一个NSOperatingSystemVersion
结构体,定义为
typedef struct { NSInteger majorVersion; NSInteger minorVersion; NSInteger patchVersion; } NSOperatingSystemVersion;
NSProcessInfo中还有一个方法可以为你做比较:
- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version
请注意 ,尽pipelogging在OS X 10.10及更高版本中可用, operatingSystemVersion
和isOperatingSystemAtLeastVersion:
存在于OS X 10.9( 可能是10.9.2 ),并按预期工作。 这意味着您不能testingNSProcessInfo
是否响应这些select器来检查您是否在OS X 10.9或10.10上运行。
在iOS上,这些方法仅在iOS 8.0之后才可用。
在命令行上:
$ sysctl kern.osrelease kern.osrelease: 12.0.0 $ sysctl kern.osversion kern.osversion: 12A269
编程方式:
#include <errno.h> #include <sys/sysctl.h> char str[256]; size_t size = sizeof(str); int ret = sysctlbyname("kern.osrelease", str, &size, NULL, 0);
达尔文版本到OS X版本:
16.xx macOS 10.12.x Sierra 15.xx OS X 10.11.x El Capitan 14.xx OS X 10.10.x Yosemite 13.xx OS X 10.9.x Mavericks 12.xx OS X 10.8.x Mountain Lion 11.xx OS X 10.7.x Lion 10.xx OS X 10.6.x Snow Leopard 9.xx OS X 10.5.x Leopard 8.xx OS X 10.4.x Tiger 7.xx OS X 10.3.x Panther 6.xx OS X 10.2.x Jaguar 5.x OS X 10.1.x Puma
有NSAppKitVersionNumber值,您可以用它来检查各种版本的AppKit,虽然他们不完全对应的操作系统版本
if (NSAppKitVersionNumber <= NSAppKitVersionNumber10_7_2) { NSLog (@"We are not running on Mountain Lion"); }
有一个cocoaAPI。 你可以从类NSProcessInfo获得os X版本的string。
获取操作系统版本string的代码如下所示。
NSString * operatingSystemVersionString = [[NSProcessInfo processInfo] operatingSystemVersionString]; NSLog(@"operatingSystemVersionString => %@" , operatingSystemVersionString);
// === >>版本10.8.2(Build 12C2034)结果值
它不被弃用。
还有kCFCoreFoundationVersionNumber,如果您只需要检查支持的最低版本,就可以使用它。 这样做的好处是可以回到10.1,并且可以在C,C ++和Objective-C中完成。
例如检查10.10或更高版本:
#include <CoreFoundation/CoreFoundation.h> if (floor(kCFCoreFoundationVersionNumber) > kCFCoreFoundationVersionNumber10_9) { printf("On 10.10 or greater."); }
您需要链接到CoreFoundation(或Foundation)框架。
它也以同样的方式在Swift中工作。 这是另一个例子:
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.") }
或者,更简单地说,这里是代码:
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"]; NSString *productVersion = [version objectForKey:@"ProductVersion"]; NSLog (@"productVersion =========== %@", productVersion);
我希望这可以帮助别人。
您可以使用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];
这是我使用的:
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"); }
在AppKit发行说明中推荐使用
如果应用程序是沙盒,读/ System / Library / CoreServices / SystemVersion.plist是不可能的
如果你有一个应用程序需要运行在10.10以及以前的版本,这里有一个解决scheme:
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 }
请注意,即使10.9似乎响应operatingSystemVersionselect器,所以我认为它只是一个私人API在10.9(但仍然有效)。
这适用于所有版本的OS X,不依赖于stringparsing或文件I / O。
有uname(3)
:
uname()
函数将以nul结束的标识当前系统的信息存储到由name
引用的结构中。
utsname
结构在<sys/utsname.h>
头文件中定义,并包含以下成员:
sysname
– 操作系统实现的名称。nodename
– 本机的networking名称。release
– 操作系统的版本级别。version
– 操作系统的版本级别。machine
– 硬件平台。
这实际上是上面的答案的汇编,还有一些进一步的指导给需要的开发者。
OS-X以多种方式在运行时提供它的版本。 每种方式都适合特定的开发情况。 我会尽量总结一下,如果我忘记了一些东西,希望其他人能够完成我的答案。
首先是获取操作系统版本的综合列表。
-
uname
命令行工具和函数提供了操作系统的unix(达尔文)版本。 虽然这不是操作系统的营销版本,但它是唯一的,所以你可以从中推导出OS-X的营销版本。 -
sysctl kern.osrelease
命令行(或sysctlbyname("kern.osrelease", str, &size, NULL, 0)
函数)将提供与uname相同的信息,稍微容易parsing。 -
Gestalt(gestaltSystemVersionMajor)
(具有“Minor
”和“BugFix
”)变体是获得营销操作系统版本的最早的(pre-Carbon!)API,仍然受到长期弃用的支持。 -
NSAppKitVersionNumber
是AppKit框架的一个float常量,它将提供与AppKit链接的所有应用程序的OS-X Appkit版本(与OS版本alignment)。 它还提供了所有可能版本的全面枚举(例如NSAppKitVersionNumber10_7_2
) -
kCFCoreFoundationVersionNumber
是一个CoreFoundation框架的float常数,与Appkit相同,在C,Obj-C和Swift中都可用于与CoreFoundation链接的所有应用程序。 它也提供了对所有OS X发布版本的全面枚举(例如kCFCoreFoundationVersionNumber10_9
) -
[[NSProcessInfo processInfo] operatingSystemVersionString];
是Obj-C中可用于OS-X和iOS应用程序的Cocoa API。 -
/System/Library/CoreServices/SystemVersion.plist
有一个资源.plist,其中包含“ProductVersion”项中的操作系统版本。 NSProcessInfo从这个文件中读取它的信息,但是你可以直接使用你select的PList-reading API。
有关每个选项的更多详细信息,请参阅上面的答案。 那里有很多的信息!