İOS sürümü nasıl kontrol edilir?


848

iOSCihaz sürümünün aşağıdaki 3.1.3 gibi şeyleri denediğimden daha büyük olup olmadığını kontrol etmek istiyorum:

[[UIDevice currentDevice].systemVersion floatValue]

ama işe yaramaz, ben sadece istiyorum:

if (version > 3.1.3) { }

Bunu nasıl başarabilirim?


5
Sunucu Not : Zamanla, bu soru 30'dan fazla cevap aldı. Yeni bir yanıt eklemeden önce çözümünüzün henüz sağlanmadığından emin olun .
Matt

3
if #available(iOS 9, *) {}Swift'te Xcode 7'yi başlatma . Xcode 9'un başlatılması, if (@available(iOS 11, *)) {}hedef-c.
Coeur

Yanıtlar:


1002

Hızlı cevap…


Swift 2.0'dan itibaren, yalnızca belirli sistemlerde çalıştırılması gereken bir kodu korumak #availableiçin ifveya içinde kullanabilirsiniz guard.

if #available(iOS 9, *) {}


Objective-C'de sistem sürümünü kontrol etmeniz ve bir karşılaştırma yapmanız gerekir.

[[NSProcessInfo processInfo] operatingSystemVersion] iOS 8 ve sonraki sürümlerinde.

Xcode 9'dan itibaren:

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


Tam cevap…

Objective-C ve Swift nadir durumlarda, cihaz veya işletim sistemi yeteneklerinin bir göstergesi olarak işletim sistemi sürümüne güvenmekten kaçınmak daha iyidir. Belirli bir özelliğin veya sınıfın mevcut olup olmadığını kontrol etmek için genellikle daha güvenilir bir yöntem vardır.

API'lerin varlığını kontrol etme:

Örneğin UIPopoverController, geçerli aygıtta kullanılabilir olup olmadığını aşağıdakileri kullanarak kontrol edebilirsiniz NSClassFromString:

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

Zayıf bağlantılı sınıflar için, sınıfa doğrudan mesaj göndermek güvenlidir. Özellikle bu, açıkça "Zorunlu" olarak bağlanmayan çerçeveler için geçerlidir. Eksik sınıflar için ifade, koşulu başarısız olarak nil olarak değerlendirir:

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

Bazı sınıflar, gibi CLLocationManagerve UIDeviceçek Cihaz özelliklerine yöntemleri sağlar:

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

Sembollerin olup olmadığını kontrol etme:

Çok zaman zaman, bir sabit olup olmadığını kontrol etmelisiniz. Bu, iOS 8'de UIApplicationOpenSettingsURLString, Ayarlar uygulamasını yüklemek için kullanılan tanıtımıyla geldi -openURL:. Değer iOS 8'den önce yoktu. Bu API'ya nil iletilmesi kilitlenecek, bu nedenle öncelikle sabitin varlığını doğrulamaya dikkat etmelisiniz:

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

İşletim sistemi sürümüyle karşılaştırma:

İşletim sistemi sürümünü kontrol etmek için nispeten nadir bir gereksinimle karşılaştığınızı varsayalım. İOS 8 ve sonraki sürümlerini hedefleyen projeler NSProcessInfoiçin, daha az hata olasılığı olan sürüm karşılaştırmaları gerçekleştirmek için bir yöntem içerir:

- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version

Eski sistemleri hedefleyen projeler systemVersionüzerinde kullanılabilir UIDevice. Apple bunu GLSprite örnek kodlarında kullanır .

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

Herhangi bir nedenle ne istediğinize karar verirseniz, systemVersionona bir dize gibi davrandığınızdan emin olun ya da düzeltme eki düzeltme numarasını (örneğin 3.1.2 -> 3.1) kesme riskiyle karşı karşıyasınız.


161
Sistem sürümünün kontrol edilmesinin gerektiği belirli durumlar vardır. Örneğin, özel n 3.x olan birkaç sınıf ve yöntem 4.0'da herkese açık hale getirildi, bu nedenle kullanılabilirliklerini kontrol ettiyseniz 3.x'te yanlış bir sonuç elde edersiniz. Buna ek olarak, UIScrollViews'un yakınlaştırma ölçeklerini işleme biçimi 3.2 ve üstü gibi ustaca değişti, bu nedenle sonuçları uygun şekilde işlemek için işletim sistemi sürümlerini kontrol etmeniz gerekir.
Brad Larson

2
iOS 3.2, -viewWillAppearbir UISplitViewController. Benim hack <iOS 4.0 olup olmadığını belirlemek ve Kök Görünümü'nde kendimi Detay Görünümü Denetleyicisine göndermek -didSelectRowAtIndexPath.
jww

10
Burada biraz dikkatli olmalısın , çünkü hiç de amaçlanmamış olabilecek [@"10.0" compare:@"10" options:NSNumericSearch]iadeler NSOrderedDescending. (Bekleyebilirim NSOrderedSame.) Bu en azından teorik bir olasılık.
SK9

Evet, az önce bir iOS 5 hatasının atlatılması gereken bir durumla karşılaştım. respondsToSelectorve diğerleri işi yapmaz - sürümleri karşılaştırmak zorunda.
Hot Licks

2
TVos tanıtımıyla bu daha da önemli hale geldi. 9.1 SDK kullanılırken TVos 9,0 olarak dönecektir. Bu yüzden sınıfı veya yöntemi (seçiciyi) en iyi şekilde kontrol edin, bundan sonra kontrol etmelisiniz NSFoundationVersionNumberve ancak bu mümkün değilse sistem sürümlerini kontrol etmelisiniz UIDevice.
rckoenes

1055
/*
 *  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")) {
    ...
}

20
+1. Bunu, gerektiğinde ekleyebileceğiniz bir başlıkta tutmak aklıma gelen en kolay çözümdür. Bazı durumlarda bu NSClassFromString kullanarak kullanılabilirliği kontrol etmekten daha güvenilirdir. Başka bir örnek iAd'de, 4.2'den önceki bir sürümde ADBannerContentSizeIdentifierPortrait kullanıyorsanız EXEC_BAD_ACCESS'i alırsınız, ancak eşdeğer ADBannerContentSizeIdentifier320x50 4.1'den sonra kullanımdan kaldırılır.
Rab

1
Bunu kullandığım başka bir yer UIPageViewController ve iOS6'da stili UIPageViewControllerTransitionStyleScroll olarak ayarlamaktır.
Paul de Lange

7
Bu 10 saniye boyunca işe yaramıyor. Örneğin 4.10 ve 4.9'u karşılaştırmak yanlış sonuç verir.
pzulw

7
İsteğe bağlı .0numaralar kullanılırken çok dikkatli olunmalıdır . Örneğin SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0.0"), iOS 7.0'da yanlış sonuç verir.
Yan

1
Ben sadece .pch dosyasında bu koyarak test edilmiş ve bunun (en azından Xcode 5 ile bina) inşaat büyük
whyoz

253

Resmi Apple belgeleri tarafından önerildiği gibi : başlık dosyasından NSFoundationVersionNumber, öğesini kullanabilirsiniz NSObjCRuntime.h.

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

40
+1 Bu aslında en güvenli ve en doğru seçenektir.
mxcl

8
Um .. NSFoundationVersionNumber_iOS_6_1iOS 5 SDK'sında mevcut değil.
13:59

2
@Kjuly eksik sürüm numaralarını kendiniz tanımlayabilirsiniz: github.com/carlj/CJAMacros/blob/master/CJAMacros/CJAMacros.h (102-130 satırına bir göz atın)
CarlJ

3
hayır, yanılıyorsunuz, NSFoundationVersionNumber_iOS_7_0 mevcut değil. Ama bunu tanımlayabiliriz #ifndef NSFoundationVersionNumber_iOS_7_0 #define NSFoundationVersionNumber_iOS_7_0 1047.00 #endif. Böyle karışıklıklardan kaçınmak için yasirmturk
Cœur

7
hayır, ancak elma NSFoundationVersionNumber_iOS_8_0iOS 9'da ekleyecekNSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1
CarlJ

111

Xcode 9'dan başlayarak, Objective-C :

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

Swift'te Xcode 7'yi başlatma :

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

Sürüm için MAJOR, MINOR veya PATCH belirtebilirsiniz ( tanımlar için bkz. Http://semver.org/ ). Örnekler:

  • iOS 11ve iOS 11.0aynı minimal versiyon
  • iOS 10, iOS 10.3, iOS 10.3.1Farklı asgari versiyonları vardır

Bu sistemlerden herhangi biri için değer girebilirsiniz:

  • iOS, macOS, watchOS,tvOS

Kapsüllerimden birinden alınan gerçek vaka örneği :

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

belgeleme


Bu, Objective-C veya Swift'te nasıl ters çevrilebilir?
Legoless

@Legolessif (...) {} else { ... }
Cœur

guardObjektif-C'de bloğu açık ve girinti olarak bırakmak yerine kullanabilir miyim else?
Legoless

@Yetersiz hayır, sadece boş bir ifblok kullanın ve ardından bir else.
Cur

1
Şu anda sahip olduğum çözüm, sadece gereksiz girinti ve boş ifbloklardan kaçınmak istedi .
Legoless

45

Bu, Xcode'daki uyumlu SDK sürümünü kontrol etmek için kullanılır, bu, Xcode'un farklı sürümlerine sahip büyük bir ekibiniz veya aynı kodu paylaşan farklı SDK'ları destekleyen birden fazla projeniz varsa:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
  //programming in iOS 8+ SDK here
#else
  //programming in lower than iOS 8 here   
#endif

Gerçekten istediğiniz şey, cihazdaki iOS sürümünü kontrol etmektir. Bunu şu şekilde yapabilirsiniz:

if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) {
  //older than iOS 8 code here
} else {
  //iOS 8 specific code here
}

Hızlı sürüm:

if let version = Float(UIDevice.current.systemVersion), version < 9.3 {
    //add lower than 9.3 code here
} else {
    //add 9.3 and above code here
}

Swift'in güncel sürümleri şu şekilde olmalıdır:

if #available(iOS 12, *) {
    //iOS 12 specific code here
} else {
    //older than iOS 12 code here
}

37

Deneyin:

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
Hem "3.1.3" hem de systemVersion hem NSStrings olduğundan, buradaki sıralamayı tersine çevirip bir karşılaştırmayı kaydetmeyesiniz? Yani: `if ([@" 3.1.3 "karşılaştır: [UIDevice currentDevice] .systemVersion seçenekleri: NSNumericSearch] == NSOrderedDescending); // OS sürümü> = 3.1.3 başka; // OS sürümü <3.1.3`
Rob

3
Bunu yapmak mantığı daha az netleştirebilir. Ancak işlem eşdeğer olmalıdır.
Jonathan Grynspan

1
İki tamsayı arasındaki bir karşılaştırma kesinlikle çok pahalı değildir.
KPM

Gerçekten bir stil meselesi. İleti gönderiminin ek yükü, ekstra tamsayı karşılaştırmasından büyük ölçüde ağır basacaktır.
Jonathan Grynspan

35

Tercih Edilen Yaklaşım

Swift 2.0'da Apple, çok daha kullanışlı bir sözdizimi kullanarak kullanılabilirlik denetimi ekledi (Daha fazlasını buradan okuyabilirsiniz ). Artık işletim sistemi sürümünü daha temiz bir sözdizimi ile kontrol edebilirsiniz:

if #available(iOS 9, *) {
    // Then we are on iOS 9
} else {
    // iOS 8 or earlier
}

Bu kontrol respondsToSelectorvb . Tercih edilir ( Swift Yenilikler ). Kodunuzu düzgün şekilde korumuyorsanız derleyici sizi her zaman uyarır.


Hızlı Swift 2.0

İOS 8'deki NSProcessInfoyenilikler daha iyi anlamsal sürüm oluşturma denetimlerine izin veriyor.

İOS 8 ve sonraki sürümlere dağıtım

İOS 8.0 veya üstünün minimum dağıtım hedefleri için NSProcessInfo operatingSystemVersionveya öğesini kullanın isOperatingSystemAtLeastVersion.

Bu, aşağıdakileri sağlayacaktır:

let minimumVersion = NSOperatingSystemVersion(majorVersion: 8, minorVersion: 1, patchVersion: 2)
if NSProcessInfo().isOperatingSystemAtLeastVersion(minimumVersion) {
    //current version is >= (8.1.2)
} else {
    //current version is < (8.1.2)
}

İOS 7'de dağıtma

Asgari dağıtım hedefleri için iOS 7.1 altında veya, ile karşılaştırmak kullanın NSStringCompareOptions.NumericSearchüzerinde UIDevice systemVersion.

Bu şöyle olur:

let minimumVersionString = "3.1.3"
let versionComparison = UIDevice.currentDevice().systemVersion.compare(minimumVersionString, options: .NumericSearch)
switch versionComparison {
    case .OrderedSame, .OrderedDescending:
        //current version is >= (3.1.3)
        break
    case .OrderedAscending:
        //current version is < (3.1.3)
        fallthrough
    default:
        break;
}

NSHipster'da daha fazla okuma .


9

Bunları her zaman Constants.h dosyamda saklıyorum:

#define IS_IPHONE5 (([[UIScreen mainScreen] bounds].size.height-568)?NO:YES) 
#define IS_OS_5_OR_LATER    ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0)
#define IS_OS_6_OR_LATER    ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0)
#define IS_OS_7_OR_LATER    ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
#define IS_OS_8_OR_LATER    ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)

Harika. Bunu .pchXCode Project'inize yerleştirmek daha iyi
Vaibhav Jhaveri

1
Tüm sabitlerimi Constants.hdosyama aktarılan dosyama yerleştiriyorum pch.
Segev

6
+(BOOL)doesSystemVersionMeetRequirement:(NSString *)minRequirement{

// eg  NSString *reqSysVer = @"4.0";


  NSString *currSysVer = [[UIDevice currentDevice] systemVersion];

  if ([currSysVer compare:minRequirement options:NSNumericSearch] != NSOrderedAscending)
  {
    return YES;
  }else{
    return NO;
  }


}

@Jef Dönemleri sürümde ondalık basamak değildir ve konuyla ilgilidir. Cevabınız dönemleri görmezden gelmez, eğer yapmazsa başarısız olur. Versiyonlamada her periyotta ayrılmış eleman tam sayıdır. Örn: '1.23.45', '1.2' olandan daha büyük çünkü ikinci '23' öğesi '2'den büyük. Eğer dönemleri ortadan kaldırırsanız aynı sayı olur.
Andres Canella

6

Nv-ios-sürüm projesinde (Apache License, Version 2.0) bulunan Version sınıfı ile iOS sürümünü almak ve karşılaştırmak kolaydır. Aşağıdaki örnek kod, iOS sürümünü döküm olarak kullanır ve sürümün 6.0'dan büyük veya buna eşit olup olmadığını kontrol eder.

// Get the system version of iOS at runtime.
NSString *versionString = [[UIDevice currentDevice] systemVersion];

// Convert the version string to a Version instance.
Version *version = [Version versionWithString:versionString];

// Dump the major, minor and micro version numbers.
NSLog(@"version = [%d, %d, %d]",
    version.major, version.minor, version.micro);

// Check whether the version is greater than or equal to 6.0.
if ([version isGreaterThanOrEqualToMajor:6 minor:0])
{
    // The iOS version is greater than or equal to 6.0.
}

// Another way to check whether iOS version is
// greater than or equal to 6.0.
if (6 <= version.major)
{
    // The iOS version is greater than or equal to 6.0.
}

Proje Sayfası: nv-ios-sürüm
TakahikoKawasaki / nv-ios-sürüm

Blog: Çalışma zamanında iOS sürümünü Sürüm sınıfı ile alın ve karşılaştırın Sürüm çalışma zamanında iOS sürümünü edinin ve Sürüm sınıfı
ile karşılaştırın


5

Hızlı Unut [[UIDevice currentDevice] systemVersion] ve NSFoundationVersionNumber kullanarak sistem sürümünü kontrol etmenin yeni yolu.

NSProcessInfo -isOperatingSystemAtLeastVersion kullanabiliriz

     import Foundation

     let yosemite = NSOperatingSystemVersion(majorVersion: 10, minorVersion: 10, patchVersion: 0)
     NSProcessInfo().isOperatingSystemAtLeastVersion(yosemite) // false

5

UIDevice + IOSVersion.h

@interface UIDevice (IOSVersion)

+ (BOOL)isCurrentIOSVersionEqualToVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionGreaterThanVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionGreaterThanOrEqualToVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionLessThanVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionLessThanOrEqualToVersion:(NSString *)iOSVersion

@end

UIDevice + IOSVersion.m

#import "UIDevice+IOSVersion.h"

@implementation UIDevice (IOSVersion)

+ (BOOL)isCurrentIOSVersionEqualToVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] == NSOrderedSame;
}

+ (BOOL)isCurrentIOSVersionGreaterThanVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] == NSOrderedDescending;
}

+ (BOOL)isCurrentIOSVersionGreaterThanOrEqualToVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] != NSOrderedAscending;
}

+ (BOOL)isCurrentIOSVersionLessThanVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] == NSOrderedAscending;
}

+ (BOOL)isCurrentIOSVersionLessThanOrEqualToVersion:(NSString *)iOSVersion
{
    return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] != NSOrderedDescending;
}

@end

4

Genel olarak, bir nesnenin mevcut olması gerekip gerekmediğine karar vermek için sürüm numarasını kontrol etmek yerine belirli bir seçici yapıp yapamayacağını sormak daha iyidir.

Bu bir seçenek olmadığında, burada biraz dikkatli olmanız gerekir, çünkü hiç de amaçlanmamış [@"5.0" compare:@"5" options:NSNumericSearch]geri dönüşler NSOrderedDescending; NSOrderedSameBurada bekleyebilirim . Bu en azından teorik bir kaygı, bence savunmaya değer.

Ayrıca, makul bir şekilde karşılaştırılamayan kötü bir sürüm girişi olasılığı da dikkate alınmalıdır. Elma üç önceden tanımlanmış sabitleri besler NSOrderedAscending, NSOrderedSameve NSOrderedDescendingfakat adlandırılan bazı şey için kullanım düşünebiliriz NSOrderedUnorderediki şey değildir karşılaştırabilirsiniz ve bu belirten bir değer döndürmek istiyorum durumunda.

Dahası, Apple'ın bir gün önceden tanımlanmış üç sabitini çeşitli dönüş değerlerine izin verecek şekilde genişletmesi imkansızdır ve bu da != NSOrderedAscendingakılsızca bir karşılaştırma yapar .

Bununla birlikte, aşağıdaki kodu göz önünde bulundurun.

typedef enum {kSKOrderedNotOrdered = -2, kSKOrderedAscending = -1, kSKOrderedSame = 0, kSKOrderedDescending = 1} SKComparisonResult;

@interface SKComparator : NSObject
+ (SKComparisonResult)comparePointSeparatedVersionNumber:(NSString *)vOne withPointSeparatedVersionNumber:(NSString *)vTwo;
@end

@implementation SKComparator
+ (SKComparisonResult)comparePointSeparatedVersionNumber:(NSString *)vOne withPointSeparatedVersionNumber:(NSString *)vTwo {
  if (!vOne || !vTwo || [vOne length] < 1 || [vTwo length] < 1 || [vOne rangeOfString:@".."].location != NSNotFound ||
    [vTwo rangeOfString:@".."].location != NSNotFound) {
    return SKOrderedNotOrdered;
  }
  NSCharacterSet *numericalCharSet = [NSCharacterSet characterSetWithCharactersInString:@".0123456789"];
  NSString *vOneTrimmed = [vOne stringByTrimmingCharactersInSet:numericalCharSet];
  NSString *vTwoTrimmed = [vTwo stringByTrimmingCharactersInSet:numericalCharSet];
  if ([vOneTrimmed length] > 0 || [vTwoTrimmed length] > 0) {
    return SKOrderedNotOrdered;
  }
  NSArray *vOneArray = [vOne componentsSeparatedByString:@"."];
  NSArray *vTwoArray = [vTwo componentsSeparatedByString:@"."];
  for (NSUInteger i = 0; i < MIN([vOneArray count], [vTwoArray count]); i++) {
    NSInteger vOneInt = [[vOneArray objectAtIndex:i] intValue];
    NSInteger vTwoInt = [[vTwoArray objectAtIndex:i] intValue];
    if (vOneInt > vTwoInt) {
      return kSKOrderedDescending;
    } else if (vOneInt < vTwoInt) {
      return kSKOrderedAscending;
    }
  }
  if ([vOneArray count] > [vTwoArray count]) {
    for (NSUInteger i = [vTwoArray count]; i < [vOneArray count]; i++) {
      if ([[vOneArray objectAtIndex:i] intValue] > 0) {
        return kSKOrderedDescending;
      }
    }
  } else if ([vOneArray count] < [vTwoArray count]) {
    for (NSUInteger i = [vOneArray count]; i < [vTwoArray count]; i++) {
      if ([[vTwoArray objectAtIndex:i] intValue] > 0) {
        return kSKOrderedAscending;
      }
    }
  }
  return kSKOrderedSame;
}
@end

4
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
        // Your code here
}

Elbette, NSFoundationVersionNumber_iOS_6_1kontrol etmek istediğiniz iOS sürümü için geçerli olarak değiştirilmelidir. Şimdi yazdıklarım, bir cihazın iOS7 veya önceki bir sürümünü çalıştırıp çalıştırmadığını test ederken muhtemelen çok kullanılacak.


4

partiye biraz geç ama iOS 8.0 ışığında bu ilgili olabilir:

kullanmaktan kaçınabiliyorsanız

[[UIDevice currentDevice] systemVersion]

Bunun yerine başka bir yöntem / sınıf / varlığın olup olmadığını kontrol edin.

if ([self.yourClassInstance respondsToSelector:@selector(<yourMethod>)]) 
{ 
    //do stuff 
}

İOS 8.0 için requestWhenInUseAuthorization'ı çağırmam gereken konum yöneticisi için yararlı buldum, ancak yöntem iOS <8 için mevcut değil


3
#define _kisiOS7 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)

if (_kisiOS7) {
            NSLog(@"iOS7 or greater")
} 
else {
           NSLog(@"Less than iOS7");
}

3

Bunun eski bir soru olduğunu biliyorum, ama birisi derleme zamanı makrolarından bahsetmiş olmalıydı Availability.h. Buradaki diğer tüm yöntemler çalışma zamanı çözümleridir ve bir başlık dosyasında, sınıf kategorisinde veya ivar tanımında çalışmaz.

Bu durumlar için,

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_6_0
  // iOS 6+ code here
#else
  // Pre iOS 6 code here
#endif

h / t bu cevap


3
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

Sonra aşağıdaki gibi bir if koşulu ekleyin: -

if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) {
   //Your code
}       

2

7.0 veya 6.0.3 gibi bir sürüm var, bu yüzden sürümü karşılaştırmak için sayısal olarak dönüştürebiliriz. sürüm 7.0 gibiyse, başka bir ".0" ekleyin ve ardından sayısal değerini alın.

 int version;
 NSString* iosVersion=[[UIDevice currentDevice] systemVersion];
 NSArray* components=[iosVersion componentsSeparatedByString:@"."];
 if ([components count]==2) {
    iosVersion=[NSString stringWithFormat:@"%@.0",iosVersion];

 }
 iosVersion=[iosVersion stringByReplacingOccurrencesOfString:@"." withString:@""];
 version=[iosVersion integerValue];

6.0.0 için

  if (version==600) {
    // Do something
  }

7.0 için

 if (version==700) {
   // Do something
 }

ondalık noktaları kaldırmak yanlış bir yaklaşımdır. 1 karakterden daha uzun bir bileşeni düşünün, örn 6.1.10. bu algoritma, 6110 > 700doğru olmayan sonuç verecektir .
ardnew

Elmanın yeni sürümleri piyasaya sürmekte kötü olduğunu anlıyorum, ancak çoğu zaman sürümün ikinci numarası asla 5'in üzerine çıkmadı, bu yüzden 10 söz konusu değil. Bu, adhoc bir yaklaşımdır, bu nedenle 2 bileşen için davayı ele alırsa, manuel olarak yapmak istiyorsanız dört büyük durumu ele alacak şekilde değiştirebilirsiniz. Her neyse, bu yaklaşım iOS6 veya 7 sırasında yorumlandı. İOS 9 ve 10'un kontrol etmek için çok daha iyi yolları var.
NaXir

2

Aşağıdaki kodu deneyin:

NSString *versionString = [[UIDevice currentDevice] systemVersion];


1

Yasimturks çözümünün bir varyasyonu olarak, beş makro yerine bir işlev ve birkaç enum değeri tanımladım. Daha zarif buluyorum, ama bu bir zevk meselesi.

Kullanımı:

if (systemVersion(LessThan, @"5.0")) ...

.h dosyası:

typedef enum {
  LessThan,
  LessOrEqual,
  Equal,
  GreaterOrEqual,
  GreaterThan,
  NotEqual
} Comparison;

BOOL systemVersion(Comparison test, NSString* version);

.m dosyası:

BOOL systemVersion(Comparison test, NSString* version) {
  NSComparisonResult result = [[[UIDevice currentDevice] systemVersion] compare: version options: NSNumericSearch];
  switch (test) {
    case LessThan:       return result == NSOrderedAscending;
    case LessOrEqual:    return result != NSOrderedDescending;
    case Equal:          return result == NSOrderedSame;
    case GreaterOrEqual: return result != NSOrderedAscending;
    case GreaterThan:    return result == NSOrderedDescending;
    case NotEqual:       return result != NSOrderedSame;
  }
}

Uygulamanızın önekini adlara, özellikle de Comparisontüre eklemelisiniz .


1

Tavsiye edilen önerilen yolu kullanarak ... başlık dosyalarında herhangi bir tanım yoksa, her zaman istediğiniz IOS sürümünün bir cihazıyla konsolda yazdırmasını sağlayabilirsiniz.

- (BOOL) isIOS8OrAbove{
    float version802 = 1140.109985;
    float version8= 1139.100000; // there is no def like NSFoundationVersionNumber_iOS_7_1 for ios 8 yet?
    NSLog(@"la version actual es [%f]", NSFoundationVersionNumber);
    if (NSFoundationVersionNumber >= version8){
        return true;
    }
    return false;
}

1

Swift'te iOS sürümünü kontrol etme çözümü

switch (UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch)) {
    case .OrderedAscending:
       println("iOS < 8.0")

    case .OrderedSame, .OrderedDescending:
       println("iOS >= 8.0")
}

Bu çözümün con: işletim sistemi sürüm numaralarına karşı kontrol etmek her ne şekilde olursa olsun kötü bir uygulamadır. Biri asla bu şekilde kod bağımlılıklarını zorlamamalıdır, her zaman bir sınıfın özelliklerini, yeteneklerini veya varlığını kontrol edin. Bunu düşün; Apple, bir sınıfın geriye dönük uyumlu bir sürümünü yayınlayabilir, eğer yaptılarsa, önerdiğiniz kod asla mantığınız bir OS sürüm numarası arar ve sınıfın varlığını DEĞİL arar.

( Bu bilgilerin kaynağı )

Swift'te sınıf varlığını kontrol etmek için çözüm

if (objc_getClass("UIAlertController") == nil) {
   // iOS 7
} else {
   // iOS 8+
}

Kullanmayın if (NSClassFromString("UIAlertController") == nil)çünkü iOS 7.1 ve 8.2 kullanarak iOS simülatöründe doğru çalışır, ancak iOS 7.1 kullanarak gerçek bir cihazda test ederseniz maalesef kod pasajının diğer kısmını asla geçmeyeceğinizi fark edeceksiniz.


Neden oy vermiyorsun? Bu çözüm Swift ve herhangi bir iOS sürümünü kullanarak mükemmel çalışır. Özellikle sınıf mevcudiyetinin kontrolü mükemmeldir.
King-Wizard

1
#define IsIOS8 (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)

0

Obj-C ++ 11'de daha genel bir sürüm (muhtemelen bu şeylerin bazılarını NSString / C işlevleriyle değiştirebilirsiniz, ancak bu daha az ayrıntılıdır.Bu size iki mekanizma sağlar. sadece ana sürümü (örneğin switch([self splitSystemVersion][0]) {case 4: break; case 5: break; }) açmak istiyorsunuz .

#include <boost/lexical_cast.hpp>

- (std::vector<int>) splitSystemVersion {
    std::string version = [[[UIDevice currentDevice] systemVersion] UTF8String];
    std::vector<int> versions;
    auto i = version.begin();

    while (i != version.end()) {
        auto nextIllegalChar = std::find_if(i, version.end(), [] (char c) -> bool { return !isdigit(c); } );
        std::string versionPart(i, nextIllegalChar);
        i = std::find_if(nextIllegalChar, version.end(), isdigit);

        versions.push_back(boost::lexical_cast<int>(versionPart));
    }

    return versions;
}

/** Losslessly parse system version into a number
 * @return <0>: the version as a number,
 * @return <1>: how many numeric parts went into the composed number. e.g.
 * X.Y.Z = 3.  You need this to know how to compare again <0>
 */
- (std::tuple<int, int>) parseSystemVersion {
    std::string version = [[[UIDevice currentDevice] systemVersion] UTF8String];
    int versionAsNumber = 0;
    int nParts = 0;

    auto i = version.begin();
    while (i != version.end()) {
        auto nextIllegalChar = std::find_if(i, version.end(), [] (char c) -> bool { return !isdigit(c); } );
        std::string versionPart(i, nextIllegalChar);
        i = std::find_if(nextIllegalChar, version.end(), isdigit);

        int part = (boost::lexical_cast<int>(versionPart));
        versionAsNumber = versionAsNumber * 100 + part;
        nParts ++;
    }

    return {versionAsNumber, nParts};
}


/** Assume that the system version will not go beyond X.Y.Z.W format.
 * @return The version string.
 */
- (int) parseSystemVersionAlt {
    std::string version = [[[UIDevice currentDevice] systemVersion] UTF8String];
    int versionAsNumber = 0;
    int nParts = 0;

    auto i = version.begin();
    while (i != version.end() && nParts < 4) {
        auto nextIllegalChar = std::find_if(i, version.end(), [] (char c) -> bool { return !isdigit(c); } );
        std::string versionPart(i, nextIllegalChar);
        i = std::find_if(nextIllegalChar, version.end(), isdigit);

        int part = (boost::lexical_cast<int>(versionPart));
        versionAsNumber = versionAsNumber * 100 + part;
        nParts ++;
    }

    // don't forget to pad as systemVersion may have less parts (i.e. X.Y).
    for (; nParts < 4; nParts++) {
        versionAsNumber *= 100;
    }

    return versionAsNumber;
}


0
float deviceOSVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
float versionToBeCompared = 3.1.3; //(For Example in your case)

if(deviceOSVersion < versionToBeCompared)
   //Do whatever you need to do. Device version is lesser than 3.1.3(in your case)
else 
   //Device version should be either equal to the version you specified or above

float versionToBeCompared = 3.1.3;derleyemiyorum bile.
Pang

0

Gerçekten çalışan hızlı örnek:

switch UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch) {
case .OrderedSame, .OrderedDescending:
    println("iOS >= 8.0")
case .OrderedAscending:
    println("iOS < 8.0")
}

NSProcessInfo kullanmayın çünkü 8.0 altında çalışmaz, bu yüzden 2016'ya kadar neredeyse işe yaramaz


0

İşte hızlı bir sürüm:

struct iOSVersion {
    static let SYS_VERSION_FLOAT = (UIDevice.currentDevice().systemVersion as NSString).floatValue
    static let iOS7 = (Version.SYS_VERSION_FLOAT < 8.0 && Version.SYS_VERSION_FLOAT >= 7.0)
    static let iOS8 = (Version.SYS_VERSION_FLOAT >= 8.0 && Version.SYS_VERSION_FLOAT < 9.0)
    static let iOS9 = (Version.SYS_VERSION_FLOAT >= 9.0 && Version.SYS_VERSION_FLOAT < 10.0)
}

Kullanımı:

if iOSVersion.iOS8 {
    //Do iOS8 code here
}

Bence Sürüm 3-6 gibi iOSVersion olmalı 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) }
Kastor
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.