Chcę sprawdzić, czy iOS
wersja urządzenia jest lepsza niż 3.1.3
próbowałem takich rzeczy:
[[UIDevice currentDevice].systemVersion floatValue]
ale to nie działa, chcę tylko:
if (version > 3.1.3) { }
Jak mogę to osiągnąć?
ios
objective-c
Jan
źródło
źródło
if #available(iOS 9, *) {}
w Swift. Począwszy od Xcode 9,if (@available(iOS 11, *)) {}
w celu-c.Odpowiedzi:
Szybka odpowiedź…
Jak Swift 2.0 można używać
#available
w sposóbif
lubguard
w kodzie ochronnym, który powinien być prowadzony tylko na niektórych systemach.if #available(iOS 9, *) {}
W Objective-C musisz sprawdzić wersję systemu i wykonać porównanie.
[[NSProcessInfo processInfo] operatingSystemVersion]
w iOS 8 i nowszych.Począwszy od Xcode 9:
if (@available(iOS 9, *)) {}
Pełna odpowiedź…
W Objective-C i Swift w rzadkich przypadkach lepiej jest unikać polegania na wersji systemu operacyjnego jako wskazania możliwości urządzenia lub systemu operacyjnego. Zwykle istnieje bardziej niezawodna metoda sprawdzania, czy dostępna jest określona funkcja lub klasa.
Sprawdzanie obecności interfejsów API:
Na przykład możesz sprawdzić, czy
UIPopoverController
jest dostępny na bieżącym urządzeniu, używającNSClassFromString
:W przypadku słabo połączonych klas wysyłanie wiadomości do klasy jest bezpieczne. W szczególności działa to w ramach, które nie są jawnie powiązane jako „Wymagane”. W przypadku brakujących klas wyrażenie przyjmuje wartość zero, co nie spełnia warunku:
Niektóre klasy, takie jak
CLLocationManager
iUIDevice
, zapewniają metody sprawdzania możliwości urządzenia:Sprawdzanie obecności symboli:
Bardzo rzadko musisz sprawdzić obecność stałej. Pojawiło się to w iOS 8 wraz z wprowadzeniem
UIApplicationOpenSettingsURLString
, używanej do ładowania aplikacji Ustawienia przez-openURL:
. Wartość nie istniała przed iOS 8. Przekazywanie wartości zerowej do tego interfejsu API ulegnie awarii, dlatego najpierw należy sprawdzić, czy istnieje stała:Porównanie z wersją systemu operacyjnego:
Załóżmy, że masz do czynienia ze stosunkowo rzadką potrzebą sprawdzenia wersji systemu operacyjnego. W przypadku projektów kierowanych na iOS 8 i
NSProcessInfo
nowsze wersje zawiera metodę przeprowadzania porównań wersji z mniejszą szansą na błąd:Projekty ukierunkowane na starsze systemy mogą korzystać
systemVersion
zUIDevice
. Apple używa go w przykładowym kodzie GLSprite .Jeśli z jakiegokolwiek powodu zdecydujesz, że
systemVersion
tego właśnie chcesz, potraktuj go jak ciąg znaków lub ryzykujesz obcięciem numeru wersji łatki (np. 3.1.2 -> 3.1).źródło
-viewWillAppear
wUISplitViewController
. Mój hack polega na ustaleniu, czy <iOS 4.0 i przesłanie go samemu do kontrolera widoku szczegółowego w widoku głównym-didSelectRowAtIndexPath
.[@"10.0" compare:@"10" options:NSNumericSearch]
zwrotyNSOrderedDescending
, które mogą wcale nie być zamierzone. (Mogę się spodziewaćNSOrderedSame
.) To jest przynajmniej teoretyczna możliwość.respondsToSelector
i inni nie wykonaliby pracy - musieli porównywać wersje.NSFoundationVersionNumber
i tylko jeśli nie jest to możliwe, powinieneś sprawdzić wersje systemuUIDevice
.źródło
.0
numerów opcjonalnych . Na przykładSYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0.0")
daje niepoprawny wynik w systemie iOS 7.0.Jak sugerują oficjalne dokumenty Apple : możesz użyć
NSFoundationVersionNumber
, zNSObjCRuntime.h
pliku nagłówka.źródło
NSFoundationVersionNumber_iOS_6_1
nie istnieje w iOS 5 SDK.#ifndef NSFoundationVersionNumber_iOS_7_0 #define NSFoundationVersionNumber_iOS_7_0 1047.00 #endif
. Aby uniknąć takich bałaganów, wybrałem makro SYSTEM_VERSION_LESS_THAN (v) z yasirmturkNSFoundationVersionNumber_iOS_8_0
iOS 9. Po prostu sprawdźNSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1
Począwszy od Xcode 9 w celu C :
Począwszy od Xcode 7 w Swift :
W przypadku wersji można określić MAJOR, MINOR lub PATCH ( definicje na stronie http://semver.org/ ). Przykłady:
iOS 11
iiOS 11.0
są w tej samej minimalnej wersjiiOS 10
,iOS 10.3
,iOS 10.3.1
Są różne wersje minimalneMożesz wprowadzić wartości dla dowolnego z tych systemów:
iOS
,macOS
,watchOS
,tvOS
Prawdziwy przykład z jednej z moich kapsułek :
dokumentacja
źródło
if (...) {} else { ... }
guard
w celu C zamiast pozostawiać blok otwarty i wcięcie welse
instrukcji?if
bloku, a następnie znakuelse
.if
bloków.Służy to do sprawdzania kompatybilności wersji SDK w Xcode, to jest, jeśli masz duży zespół z różnymi wersjami Xcode lub wieloma projektami obsługującymi różne SDK, które współużytkują ten sam kod:
Naprawdę chcesz sprawdzić wersję iOS na urządzeniu. Możesz to zrobić w ten sposób:
Wersja szybka:
Obecne wersje swift powinny używać tego:
źródło
Próbować:
źródło
Preferowane podejście
W Swift 2.0 Apple dodał sprawdzanie dostępności przy użyciu znacznie wygodniejszej składni (czytaj więcej tutaj ). Teraz możesz sprawdzić wersję systemu operacyjnego, stosując czystszą składnię:
Jest to preferowane zamiast sprawdzania
respondsToSelector
itp. ( Co nowego w Swift ). Teraz kompilator zawsze ostrzega, jeśli nie strzeżesz poprawnie swojego kodu.Pre Swift 2.0
Nowością w iOS 8 jest
NSProcessInfo
możliwość lepszej kontroli semantycznej wersji.Wdrażanie w systemie iOS 8 i nowszych
Dałoby to:
Wdrażanie na iOS 7
Dałoby to:
Więcej lektur na NSHipster .
źródło
Zawsze przechowuję je w moim pliku Constants.h:
źródło
.pch
pliku swojego projektu XCodeConstants.h
pliku zaimportowanym do mojegopch
pliku.źródło
Dzięki klasie Version zawartej w projekcie nv-ios-version (Licencja Apache, wersja 2.0) można łatwo uzyskać i porównać wersję iOS. Przykładowy kod poniżej zrzuca wersję iOS i sprawdza, czy wersja jest większa lub równa 6.0.
Strona projektu: wersja nv-ios TakahikoKawasaki / wersja
nv-ios
Blog: Pobierz i porównaj wersję iOS w czasie wykonywania z klasą Version
Pobierz i porównaj wersję iOS w czasie wykonywania z klasą Version
źródło
Nowy sposób sprawdzenia wersji systemu za pomocą szybkiego Forget [[UIDevice currentDevice] systemVersion] i NSFoundationVersionNumber.
Możemy użyć NSProcessInfo -isOperatingSystemAtLeastVersion
źródło
UIDevice + IOSVersion.h
UIDevice + IOSVersion.m
źródło
Ogólnie lepiej jest zapytać, czy obiekt może wykonać dany selektor, niż sprawdzać numer wersji, aby zdecydować, czy musi on być obecny.
Jeśli nie jest to opcja, musisz być nieco ostrożny, ponieważ
[@"5.0" compare:@"5" options:NSNumericSearch]
zwroty,NSOrderedDescending
które mogą nie być wcale zamierzone; Mogę sięNSOrderedSame
tu spodziewać . Jest to przynajmniej kwestia teoretyczna, przed którą moim zdaniem warto się bronić.Warto również wziąć pod uwagę możliwość wprowadzenia złej wersji, której nie można racjonalnie porównać. Jabłko dostarcza trzy predefiniowane stałe
NSOrderedAscending
,NSOrderedSame
aNSOrderedDescending
jednak mogę myśleć o użyciu dla niektórych rzeczy zwanejNSOrderedUnordered
w przypadku nie mogę porównać dwie rzeczy i chcę zwrócić wartość wskazującą ten.Co więcej, nie jest niemożliwe, że Apple pewnego dnia rozszerzy swoje trzy predefiniowane stałe, aby umożliwić różne wartości zwracane, co czyni porównanie
!= NSOrderedAscending
nierozsądnym.Powiedziawszy to, rozważ następujący kod.
źródło
Gdzie oczywiście
NSFoundationVersionNumber_iOS_6_1
należy zmienić na odpowiednie dla wersji iOS, którą chcesz sprawdzić. To, co teraz napisałem, prawdopodobnie będzie często używane podczas testowania, czy urządzenie ma system iOS7 lub poprzednią wersję.źródło
nieco późno na imprezę, ale w świetle iOS 8.0 może to mieć znaczenie:
jeśli możesz uniknąć używania
[[UIDevice currentDevice] systemVersion]
Zamiast tego sprawdź, czy istnieje metoda / klasa / cokolwiek innego.
Okazało się, że jest to przydatne dla menedżera lokalizacji, w którym muszę wywołać requestWhenInUseAuthorization dla iOS 8.0, ale metoda nie jest dostępna dla iOS <8
źródło
źródło
Wiem, że to stare pytanie, ale ktoś powinien wspomnieć o makrach czasu kompilacji
Availability.h
. Wszystkie inne metody tutaj są rozwiązaniami uruchomieniowymi i nie będą działać w pliku nagłówkowym, kategorii klasy lub definicji ivar.W takich sytuacjach użyj
h / t tej odpowiedzi
źródło
Następnie dodaj warunek if w następujący sposób:
źródło
Istnieją wersje takie jak 7.0 lub 6.0.3, więc możemy po prostu przekonwertować wersję na numeryczną w celu porównania. jeśli wersja jest jak 7.0, po prostu dodaj do niej kolejny „.0”, a następnie pobierz jego wartość liczbową.
Dla 6.0.0
dla 7.0
źródło
6.1.10
. wtedy algorytm da wynik6110 > 700
, co nie jest poprawne.Wypróbuj poniższy kod:
źródło
Tylko do pobrania wartości ciągu wersji systemu operacyjnego:
źródło
Jako wariant rozwiązania yasimturks zdefiniowałem jedną funkcję i kilka wartości wyliczeniowych zamiast pięciu makr. Uważam, że jest bardziej elegancki, ale to kwestia gustu.
Stosowanie:
plik .h:
plik .m:
Powinieneś dodać prefiks aplikacji do nazw, szczególnie do
Comparison
typu.źródło
Korzystając z zalecanego zalecanego sposobu ... jeśli nie ma definicji w plikach nagłówków, zawsze możesz uzyskać wersję drukującą ją na konsoli z urządzeniem o pożądanej wersji IOS.
źródło
Rozwiązanie do sprawdzania wersji iOS w Swift
Wada tego rozwiązania: sprawdzanie przy użyciu numerów wersji systemu operacyjnego jest po prostu złą praktyką. Nigdy nie należy w ten sposób ustalać zależności kodu, zawsze sprawdzać cechy, możliwości lub istnienie klasy. Rozważ to; Apple może wydać kompatybilną z poprzednią wersją klasę, jeśli tak, to sugerowany kod nigdy go nie użyje, ponieważ logika szuka numeru wersji systemu operacyjnego, a NIE istnienia klasy.
( Źródło tej informacji )
Rozwiązanie do sprawdzania istnienia klasy w Swift
Nie używaj,
if (NSClassFromString("UIAlertController") == nil)
ponieważ działa poprawnie na symulatorze iOS z iOS 7.1 i 8.2, ale jeśli testujesz na prawdziwym urządzeniu z iOS 7.1, niestety zauważysz, że nigdy nie przejdziesz przez pozostałą część fragmentu kodu.źródło
źródło
Bardziej ogólna wersja w Obj-C ++ 11 (prawdopodobnie możesz zastąpić niektóre z tych rzeczy funkcjami NSString / C, ale jest to mniej szczegółowe. To daje dwa mechanizmy. SplitSystemVersion daje tablicę wszystkich części, co jest przydatne, jeśli po prostu chcesz włączyć wersję główną (np
switch([self splitSystemVersion][0]) {case 4: break; case 5: break; }
.).źródło
Spróbuj tego
źródło
źródło
float versionToBeCompared = 3.1.3;
nie można nawet skompilować.Szybki przykład, który faktycznie działa:
Nie używaj NSProcessInfo, ponieważ nie działa pod wersją 8.0, więc jest prawie bezużyteczne do 2016 roku
źródło
Oto szybka wersja:
Stosowanie:
źródło
struct iOSVersion { static let SYS_VERSION_FLOAT = (UIDevice.currentDevice().systemVersion as NSString).floatValue static let iOS7 = (iOSVersion.SYS_VERSION_FLOAT < 8.0 && iOSVersion.SYS_VERSION_FLOAT >= 7.0) static let iOS8 = (iOSVersion.SYS_VERSION_FLOAT >= 8.0 && iOSVersion.SYS_VERSION_FLOAT < 9.0) static let iOS9 = (iOSVersion.SYS_VERSION_FLOAT >= 9.0 && iOSVersion.SYS_VERSION_FLOAT < 10.0) }