ios - tool - title tag




Wie ermittle ich die OS-Version zur Laufzeit in OS X oder iOS(ohne Gestalt zu verwenden)? (8)

Die Funktion Gestalt () in CarbonCore/OSUtils.h wurde ab OS X 10.8 Mountain Lion eingestellt.

Ich benutze diese Funktion oft, um die Version des OS X-Betriebssystems zur Laufzeit zu testen (siehe nachstehendes Beispiel).

Welche andere API könnte verwendet werden, um die Betriebssystemversion von OS X zur Laufzeit in einer Cocoa-Anwendung zu überprüfen?

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);
}

Auf der Befehlszeile:

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

Programmatisch:

#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 zu OS X-Version:

17.x.x. macOS 10.13.x High Sierra
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

Ein Beispiel zum Abrufen und Testen von Versionen:

#include <string.h>
#include <stdio.h>
#include <sys/sysctl.h>

/* kernel version as major minor component*/
struct kern {
    short int version[3];
};

/* return the kernel version */
void GetKernelVersion(struct kern *k) {
   static short int version_[3] = {0};
   if (!version_[0]) {
      // just in case it fails someday
      version_[0] = version_[1] = version_[2] = -1;
      char str[256] = {0};
      size_t size = sizeof(str);
      int ret = sysctlbyname("kern.osrelease", str, &size, NULL, 0);
      if (ret == 0) sscanf(str, "%hd.%hd.%hd", &version_[0], &version_[1], &version_[2]);
    }
    memcpy(k->version, version_, sizeof(version_));
}

/* compare os version with a specific one
0 is equal
negative value if the installed version is less
positive value if the installed version is more
*/
int CompareKernelVersion(short int major, short int minor, short int component) {
    struct kern k;
    GetKernelVersion(&k);
    if ( k.version[0] !=  major) return major - k.version[0];
    if ( k.version[1] !=  minor) return minor - k.version[1];
    if ( k.version[2] !=  component) return component - k.version[2];
    return 0;
}

int main() {
   struct kern kern;
   GetKernelVersion(&kern);
   printf("%hd %hd %hd\n", kern.version[0], kern.version[1], kern.version[2]);

   printf("up: %d %d eq %d %d low %d %d\n",
        CompareKernelVersion(17, 0, 0), CompareKernelVersion(16, 3, 0),
        CompareKernelVersion(17, 3, 0), CompareKernelVersion(17,3,0),
        CompareKernelVersion(17,5,0), CompareKernelVersion(18,3,0));


}

Ergebnis auf meiner Maschine MacOs High Sierra 10.13.2

17 3 0
up: -3 -1 eq 0 0 low 2 1

Da ist uname(3) :

Die Funktion uname() speichert nul-terminierte Informationsfolgen, die das aktuelle System in der durch den name referenzierten Struktur identifizieren.

Die Struktur von utsname ist in der <sys/utsname.h> definiert und enthält die folgenden Member:

  • sysname - Name der Betriebssystemimplementierung.
  • nodename - Netzwerkname dieses nodename .
  • release - Freigabestufe des Betriebssystems.
  • version - Versionsstufe des Betriebssystems.
  • machine - Maschinenhardwareplattform.

Dies ist eigentlich eine Zusammenstellung der Antworten oben, mit einigen weiteren Hinweisen für den Entwickler in Not.

OS-X stellt seine Version in Runtime auf verschiedene Arten zur Verfügung. Jeder Weg passt besser zu einem bestimmten Entwicklungsszenario. Ich werde versuchen, sie alle zusammenzufassen, und hoffe, dass andere meine Antwort vervollständigen werden, wenn ich etwas vergessen habe.

Erstens, die umfassende Liste der Möglichkeiten, die OS-Version zu erhalten.

  1. Das Befehlszeilentool und die Funktion uname die Unix-Version (Darwin) des Betriebssystems bereit. Obwohl dies nicht die Marketing-Version des Betriebssystems ist, ist es eindeutig damit ausgerichtet, so dass Sie daraus die OS-X-Marketing-Version ableiten können.
  2. sysctl kern.osrelease Befehlszeile (oder sysctlbyname("kern.osrelease", str, &size, NULL, 0) -Funktion) liefert die gleichen Informationen wie uname, marginal einfacher zu parsen.
  3. Gestalt(gestaltSystemVersionMajor) (mit seinen Varianten " Minor " und BugFix ") ist die älteste (Pre-Carbon!) API, um die noch lange veraltete Version des Marketing OS zu erhalten. Verfügbar in C aus dem CoreServices Framework, aber nicht empfohlen.
  4. NSAppKitVersionNumber ist eine Float-Konstante des AppKit-Frameworks, die die OS-X-Appkit-Version (ausgerichtet auf die Betriebssystemversion) bereitstellt, die für alle Anwendungen verfügbar ist, die mit AppKit verknüpft sind. Es bietet auch eine umfassende Aufzählung aller möglichen Versionen (zB NSAppKitVersionNumber10_7_2 )
  5. kCFCoreFoundationVersionNumber ist eine CoreFoundation-Framework-Float-Konstante, die mit dem AppKit-Pendant identisch ist und für alle Apps verfügbar ist, die mit CoreFoundation in C, Obj-C und Swift verknüpft sind. Es bietet auch eine umfassende Aufzählung über alle OS X freigegebenen Versionen (zB kCFCoreFoundationVersionNumber10_9 )
  6. [[NSProcessInfo processInfo] operatingSystemVersionString]; ist eine Cocoa-API, die in Obj-C für OS-X- und iOS-Anwendungen verfügbar ist.
  7. Es gibt eine Ressource .plist in /System/Library/CoreServices/SystemVersion.plist die unter anderem die Betriebssystemversion im Schlüssel "ProductVersion" enthält. NSProcessInfo liest seine Informationen aus dieser Datei, aber Sie können dies direkt mit Ihrer PList-Lese-API Ihrer Wahl tun.

Weitere Informationen zu den einzelnen Optionen finden Sie in den Antworten oben. Dort gibt es viele Informationen!


Es gibt auch kCFCoreFoundationVersionNumber, das verwendet werden kann, wenn Sie nur nach einer zu unterstützenden Mindestversion suchen müssen. Dies hat den Vorteil, dass es auf 10.1 zurückgeht und in C, C ++ und Objective-C ausgeführt werden kann.

Um zum Beispiel nach 10.10 oder höher zu suchen:

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

Sie müssen mit dem CoreFoundation (oder Foundation) Framework verlinken.

Es funktioniert auch in Swift genau so. Hier ist ein anderes Beispiel:

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.")
}

Es gibt eine Kakao-API. Sie können eine os X-Versionszeichenfolge von der Klasse NSProcessInfo abrufen.

Der Code zum Abrufen der Betriebssystem-Versionsstring ist unten.

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

NSLog(@"operatingSystemVersionString => %@" , operatingSystemVersionString);

// === >> Version 10.8.2 (Build 12C2034) Ergebniswert

Es ist nicht veraltet.


Oder, um es einfacher zu sagen, hier ist der Code:

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

Ich hoffe, das hilft jemandem.


Unter OS X 10.10 (und iOS 8.0) können Sie [[NSProcessInfo processInfo] operatingSystemVersion] das eine NSOperatingSystemVersion Struktur NSOperatingSystemVersion , die als definiert ist

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

Es gibt auch eine Methode in NSProcessInfo, die den Vergleich für Sie durchführt:

- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version

Achtung , obwohl es in OS X 10.10 und höher isOperatingSystemAtLeastVersion: existieren sowohl operatingSystemVersion als auch isOperatingSystemAtLeastVersion: unter OS X 10.9 ( wahrscheinlich 10.9.2 ) und funktionieren wie erwartet. NSProcessInfo bedeutet, dass Sie nicht testen müssen, ob NSProcessInfo auf diese Selektoren reagiert, um zu überprüfen, ob Sie unter OS X 10.9 oder 10.10 ausgeführt werden.

Auf iOS sind diese Methoden effektiv nur seit iOS 8.0 verfügbar.


Wenn Sie eine App haben, die am 10.10 sowie frühere Versionen ausgeführt werden muss, ist hier eine Lösung:

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
}

Beachten Sie, dass sogar 10.9 auf den Selektor operatingSystemVersion zu reagieren scheint, daher denke ich, dass es in 10.9 nur eine private API war (die aber immer noch funktioniert).

Dies funktioniert auf allen Versionen von OS X und ist nicht auf String-Parsing oder Datei-I / O angewiesen.





carbon