如何知道该应用运行的Mac OS是什么?

时间:2012-06-15 17:01:11

标签: objective-c xcode macos cocoa osx-mountain-lion

我在一些项目中看到过类似的东西:

#if .....
    code...
#endif

但我现在找不到了...
比方说,例如,如果应用程序在10.8运行,应用程序会执行1项操作,如果不是应用程序执行其他操作。 什么代码来检查它是否在10.8上运行?
感谢。

7 个答案:

答案 0 :(得分:23)

你可能会问错误的问题。除非极少数情况下,您不应该关心用户正在运行的系统版本。相反,您应该检查您感兴趣的特定事物是否可用。

例如,如果Apple在Mac OS X 10.9中引入了您想要使用的MagicHologram类,则不会检查用户是否正在运行Mac OS X 10.9。而是检查MagicHologram类是否可用。如果是,您可以使用它。如果没有,它就不可用。它甚至不重要。也许他们正在跑10.8。但也许是五年之后,Apple决定完全放弃MagicHologram课程。

(另外,请记住,您需要弱连接到HologramKit,即提供MagicHologram类的库。)

同样,如果他们为NSString引入了一个新方法,而不是检查操作系统版本,你将检查NSString是否知道新方法。

也就是说,NSApplication.h包含一个名为NSAppKitVersionNumber的外部常量。您可以将此与NSAppKitVersionNumber10_7之类的常量进行比较,其中(应该注意)是1138之类的数字,而不是10.7。这里只有少数几个适合的地方,主要是那些类是私有的和没有文档的,但在记录之前得到了重大改变,并成为SDK公共部分的一部分。此外,如果您想避免自那以后修复的特定错误,可能会有所帮助。

回顾一下:

  1. 检测个别类别和方法,这些类别和方法应覆盖99.44%的案例。
  2. 使用NSAppKitVersionNumberNSAppKitVersionNumber10_7来涵盖那些会对您进行分类或方法检测的情况。
  3. 前两点涵盖所有正常案例。你不应该再进一步了。但是如果你必须有基于人性化版本的行为,请看下面的abarnert答案。这是获得它们的最佳方式。
  4. 请勿使用operatingSystemVersionString,这是特别列为不安全的解析。
  5. 参考资料/更多信息:

    • SDK Compatibility Guide“如果您希望应用程序针对特定版本或多个版本的iOS或Mac OS X,请阅读本文档。”

答案 1 :(得分:11)

快速做法是:

if ( NSAppKitVersionNumber >= NSAppKitVersionNumber10_7 ) {

    // Do stuff for Lion or later
}

更多here

您可以在NSApplication.h中看到所有可用的常量,您可以通过在Xcode中使用Open Quickly ...(Cmd-Shift O)来获取这些常量。

如果您愿意,头文件会提供一些令人惊讶的有趣的阅读材料。

答案 2 :(得分:4)

正如其他人上面所说(我会选择Steven Fisher的回答),你通常不想得到版本号。

如果您只需要对主要的OS X版本进行比较,直到您正在使用的当前SDK的版本,NSAppKitVersionNumber(如Monolo的回答中)是正确的方法。

如果您确实需要出于某种原因获取版本号(例如,为了记录关于您的用户的分析,那么您可以决定何时停止支持10.6.0-10.6.5),这里是如何做到的:< / p>

#import <CoreServices/CoreServices.h>
SInt32 majorVersion, minorVersion, bugFixVersion;
Gestalt(gestaltSystemVersionMajor, &majorVersion);
Gestalt(gestaltSystemVersionMinor, &minorVersion);
Gestalt(gestaltSystemVersionBugFix, &bugFixVersion);  

对于10.7.3,这给majorVersion = 10,minorVersion = 7,bugFixVersion = 3.

10.7文档删除了直接建议使用Gestalt作为获取操作系统版本的方式的段落,但它仍然没有被弃用或遗留,并且没有其他建议。事实上,获取此信息的每种其他方式(解析 - [NSProcessInfo operatingSystemVersionString],在“kern.osrelease”上调用sysctlbyname并将Darwin内核版本转换为OS X版本等)在某处明确地反指示。所以,如果你真的想要这样做,这就是它的方法。

请记住,正如系统6.0.4的发行说明早在1989年所述,这个新API可能不是永久性的,可能会在未来的操作系统版本中删除。

答案 3 :(得分:2)

您可以从uname -r命令获取当前版本(实际上是内核版本,但很容易映射到Mac OS X版本),sw_vers命令为您提供版本名称,版本和构建标识符,或来自Gestalt()函数(无论如何,在当前版本的Mac OS X上)。最安全的方法可能是读取sw_vers的输出,该输出采用易于解析的稳定格式。

请注意,您可能不想知道您所使用的操作系统版本。您可能想要做的是测试特定功能是否可用。您可以通过弱链接框架,弱类引用或检查类是否响应适合您感兴趣的功能的选择器来实现此目的。

答案 4 :(得分:2)

正如Steven Fisher所说,你不应该检查系统版本,而应该检查你想要使用的类或方法的可用性。

检查特定类是否可用

if ([NSHologram class]) {
   // Create an instance of the class and use it.
} else {
   // The Hologram class is not available.
}

要检查特定方法是否可用,请使用

NSString* hologramText = @"Hologram";
if ([hologramText respondsToSelector:@selector(convertHologram)]) {
    [hologramText convertHologram];
}

然而,对于方法检查,该方法必须在您构建应用程序的系统上可用,否则您将收到编译错误。

答案 5 :(得分:0)

这是我如何做的代码。我喜欢这种方式,主要是因为我没有A)依赖于NSTask或B)依赖于许多进程可以访问的任何文件I / O.

static NSString* const kVarSysInfoVersionFormat  = @"%@.%@.%@ (%@)";
static NSString* const kVarSysInfoKeyOSVersion = @"kern.osrelease";
static NSString* const kVarSysInfoKeyOSBuild   = @"kern.osversion";

- (NSString *) _strControlEntry:(NSString *)ctlKey {

    size_t size = 0;
    if ( sysctlbyname([ctlKey UTF8String], NULL, &size, NULL, 0) == -1 ) return nil;

    char *machine = calloc( 1, size );

    sysctlbyname([ctlKey UTF8String], machine, &size, NULL, 0);
    NSString *ctlValue = [NSString stringWithCString:machine encoding:[NSString defaultCStringEncoding]];

    free(machine); return ctlValue;
}

- (NSString *) getOSVersionInfo {

    NSString *darwinVer = [self _strControlEntry:kVarSysInfoKeyOSVersion];
    NSString *buildNo = [self _strControlEntry:kVarSysInfoKeyOSBuild];
    if ( !darwinVer || !buildNo ) return nil;

    NSString *majorVer = @"10", *minorVer = @"x", *bugFix = @"x";
    NSArray *darwinChunks = [darwinVer componentsSeparatedByCharactersInSet:[NSCharacterSet punctuationCharacterSet]];

    if ( [darwinChunks count] > 0 ) {

        NSInteger firstChunk = [(NSString *)[darwinChunks objectAtIndex:0] integerValue];
        minorVer = [NSString stringWithFormat:@"%ld", (firstChunk - 4)];
        bugFix = [darwinChunks objectAtIndex:1];

    } return [NSString stringWithFormat:kVarSysInfoVersionFormat, majorVer, minorVer, bugFix, buildNo];
}

享受!

答案 6 :(得分:-3)

您可以获得如下操作系统版本:

NSString *version = [[NSProcessInfo processInfo] operatingSystemVersionString];

NSLog(version);

输出:

screenshot

<小时/> 而且我看到你想得到的版本。它可以这样做:

NSString *version = [[NSProcessInfo processInfo] operatingSystemVersionString];

NSRange range = NSMakeRange(8, 4);
NSString *justVersion = [version substringWithRange: range];

NSLog(@"%@", justVersion);

结果:

screenshot

检查:

if ([justVersion isEqualToString:@"10.7"]) {
    code...
}
else {
    ...
}