908 Stimmen

Wie kann ich die iOS-Version überprüfen?

Ich möchte prüfen, ob die iOS Version des Geräts größer ist als 3.1.3 Ich habe Dinge ausprobiert wie:

[[UIDevice currentDevice].systemVersion floatValue]

aber es funktioniert nicht, ich will nur eine:

if (version > 3.1.3) { }

Wie kann ich das erreichen?

7 Stimmen

Anmerkung des Moderators : Im Laufe der Zeit sind auf diese Frage über 30 Antworten eingegangen. Bevor Sie eine neue Antwort hinzufügen, sollten Sie sicher dass Ihre Lösung nicht bereits zur Verfügung gestellt wurde.

5 Stimmen

Xcode 7 starten, if #available(iOS 9, *) {} in Swift. Xcode 9 starten, if (@available(iOS 11, *)) {} in objektiv-c.

0 Stimmen

1060voto

yasirmturk Punkte 1903
/*
 *  System Versioning Preprocessor Macros
 */ 

#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

/*
 *  Usage
 */ 

if (SYSTEM_VERSION_LESS_THAN(@"4.0")) {
    ...
}

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"3.1.1")) {
    ...
}

21 Stimmen

+1. Die einfachste Lösung, die ich mir vorstellen kann, ist, dies in einer Kopfzeile unterzubringen, die Sie bei Bedarf einfügen können. In mehreren Fällen ist dies zuverlässiger als die Überprüfung der Verfügbarkeit mit NSClassFromString. Ein weiteres Beispiel ist iAd. Wenn Sie ADBannerContentSizeIdentifierPortrait in einer Version vor 4.2 verwenden, erhalten Sie EXEC_BAD_ACCESS, aber der entsprechende ADBannerContentSizeIdentifier320x50 ist nach 4.1 veraltet.

1 Stimmen

Ein weiterer Ort, den ich verwenden, ist mit UIPageViewController und Einstellung der Stil UIPageViewControllerTransitionStyleScroll in iOS6.

0 Stimmen

Das ist perfekt, das sollte die akzeptierte Antwort sein. Ich würde nur hinzufügen, dass für Methoden nur für die Version größer als die Basisversion noch überprüft werden sollte mit respondsToSelector .

1051voto

Justin Punkte 20271

Die schnelle Antwort

Ab Swift 2.0 können Sie #available in einem if ou guard zum Schutz von Code, der nur auf bestimmten Systemen ausgeführt werden soll.

if #available(iOS 9, *) {}

In Objective-C müssen Sie die Systemversion prüfen und einen Vergleich durchführen.

[[NSProcessInfo processInfo] operatingSystemVersion] in iOS 8 und höher.

Ab Xcode 9:

if (@available(iOS 9, *)) {}

Die vollständige Antwort

In Objective-C und in seltenen Fällen in Swift ist es besser, sich nicht auf die Version des Betriebssystems als Hinweis auf die Fähigkeiten des Geräts oder des Betriebssystems zu verlassen. In der Regel gibt es eine zuverlässigere Methode, um zu prüfen, ob eine bestimmte Funktion oder Klasse verfügbar ist.

Überprüfung auf das Vorhandensein von APIs:

Sie können zum Beispiel prüfen, ob UIPopoverController ist auf dem aktuellen Gerät verfügbar mit NSClassFromString :

if (NSClassFromString(@"UIPopoverController")) {
    // Do something
}

Bei schwach verknüpften Klassen ist es sicher, die Klasse direkt zu melden. Dies gilt insbesondere für Frameworks, die nicht explizit als "Required" verlinkt sind. Bei fehlenden Klassen wird der Ausdruck zu Null ausgewertet, wodurch die Bedingung nicht erfüllt wird:

if ([LAContext class]) {
    // Do something
}

Einige Klassen, wie CLLocationManager y UIDevice bieten Methoden zur Überprüfung der Gerätefähigkeiten:

if ([CLLocationManager headingAvailable]) {
    // Do something
}

Überprüfung auf das Vorhandensein von Symbolen:

Gelegentlich müssen Sie prüfen, ob eine Konstante vorhanden ist. Dies geschah in iOS 8 mit der Einführung von UIApplicationOpenSettingsURLString zum Laden der App Einstellungen über -openURL: . Der Wert existierte vor iOS 8 nicht. Die Übergabe von nil an diese API führt zum Absturz, daher müssen Sie zuerst die Existenz der Konstante überprüfen:

if (&UIApplicationOpenSettingsURLString != NULL) {
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}

Vergleich mit der Version des Betriebssystems:

Nehmen wir an, Sie müssen relativ selten die Version des Betriebssystems überprüfen. Für Projekte, die auf iOS 8 und höher abzielen, NSProcessInfo enthält eine Methode zur Durchführung von Versionsvergleichen mit geringerer Fehlerwahrscheinlichkeit:

- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version

Projekte, die auf ältere Systeme abzielen, können Folgendes nutzen systemVersion en UIDevice . Apple verwendet es in seinen GLSprite Beispiel-Code.

// A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer
// class is used as fallback when it isn't available.
NSString *reqSysVer = @"3.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) {
    displayLinkSupported = TRUE;
}

Wenn Sie aus irgendeinem Grund beschließen, dass systemVersion ist das, was Sie wollen, stellen Sie sicher, dass Sie es als Zeichenkette behandeln, oder Sie riskieren, die Patch-Revisionsnummer abzuschneiden (z.B. 3.1.2 -> 3.1).

163 Stimmen

Es gibt bestimmte Fälle, in denen eine Überprüfung der Systemversion gerechtfertigt ist. Zum Beispiel wurden einige Klassen und Methoden, die in 3.x privat waren, in 4.0 öffentlich gemacht, so dass man ein falsches Ergebnis erhalten würde, wenn man einfach ihre Verfügbarkeit in 3.x prüft. Außerdem hat sich die Art und Weise, wie UIScrollViews die Zoom-Skalen handhaben, in 3.2 und höher geringfügig geändert, so dass man die Betriebssystemversionen prüfen muss, um die Ergebnisse entsprechend zu verarbeiten.

2 Stimmen

IOS 3.2 scheint nicht zu senden -viewWillAppear in einem UISplitViewController . Mein Hack ist es, festzustellen, ob < iOS 4.0, und senden Sie es an den Detail View Controller selbst in der Root View's -didSelectRowAtIndexPath .

10 Stimmen

Sie müssen hier ein wenig vorsichtig sein, denn [@"10.0" compare:@"10" options:NSNumericSearch] gibt zurück. NSOrderedDescending was vielleicht gar nicht beabsichtigt ist. (Ich könnte erwarten NSOrderedSame .) Dies ist zumindest eine theoretische Möglichkeit.

253voto

CarlJ Punkte 9401

Wie von der Kommission vorgeschlagen offizielle Apple-Dokumente : Sie können die NSFoundationVersionNumber , aus dem NSObjCRuntime.h Header-Datei.

if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
    // here you go with iOS 7
}

42 Stimmen

+1 Dies ist in der Tat die am sichersten und genaueste Option hier.

8 Stimmen

Ähm NSFoundationVersionNumber_iOS_6_1 gibt es im iOS 5 SDK nicht.

0 Stimmen

@Nate Ich verwende selbst iOS 7 SKD. Was ich jetzt getan habe, ist zu prüfen, ob NSFoundationVersionNumber_iOS_6_1 definiert oder nicht, wenn nicht, ist es natürlich unter iOS 7. Ich muss diesen Fall betrachten, weil ich sicherstellen muss, dass die Lib für jeden Entwickler geeignet ist, einschließlich diejenigen, die noch iOS 5 SDK verwenden. Wie auch immer, das ist eine gute Lösung, ich stimme mit ihm. Das ist, warum ich es verwenden. ;)

141voto

Cœur Punkte 34332

Beim Start von Xcode 9, in Objektiv-C :

if (@available(iOS 11, *)) {
    // iOS 11 (or newer) ObjC code
} else {
    // iOS 10 or older code
}

Starten Sie Xcode 7, in Schnell :

if #available(iOS 11, *) {
    // iOS 11 (or newer) Swift code
} else {
    // iOS 10 or older code
}

Für die Version können Sie die MAJOR, die MINOR oder die PATCH angeben (siehe http://semver.org/ für Definitionen). Beispiele:

  • iOS 11 y iOS 11.0 sind die gleiche Minimalversion
  • iOS 10 , iOS 10.3 , iOS 10.3.1 sind verschiedene Minimalversionen

Sie können Werte für jedes dieser Systeme eingeben:

  • iOS , macOS , watchOS , tvOS

Reales Fallbeispiel aus eine meiner Schoten :

if #available(iOS 10.0, tvOS 10.0, *) {
    // iOS 10+ and tvOS 10+ Swift code
} else {
    // iOS 9 and tvOS 9 older code
}

Dokumentation

0 Stimmen

Wie kann dies entweder in Objective-C oder Swift umgekehrt werden?

0 Stimmen

@Beinlos if (...) {} else { ... }

0 Stimmen

Kann ich die guard in Objective-C zu verwenden, anstatt den Block offen zu lassen und die Einrückung in else Aussage?

39voto

Jonathan Grynspan Punkte 43004

Versuchen Sie es:

NSComparisonResult order = [[UIDevice currentDevice].systemVersion compare: @"3.1.3" options: NSNumericSearch];
if (order == NSOrderedSame || order == NSOrderedDescending) {
    // OS version >= 3.1.3
} else {
    // OS version < 3.1.3
}

2 Stimmen

Warum nicht hier die Reihenfolge umkehren und einen Vergleich sparen, da sowohl @"3.1.3" als auch systemVersion NSStrings sind? D.h.: ` if ([@"3.1.3" compare: [UIDevice aktuellesGerät].systemVersion Optionen: NSNumericSearch] == NSOrderedDescending) ;// OS Version >= 3.1.3 else ;// OS Version < 3.1.3`

3 Stimmen

Dadurch wird die Logik möglicherweise weniger klar. Der Vorgang sollte jedoch gleichwertig sein.

1 Stimmen

Ein Vergleich zwischen zwei ganzen Zahlen ist sicherlich nicht sehr teuer.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X