Bagaimana cara memeriksa versi iOS?


848

Saya ingin memeriksa apakah iOSversi perangkat lebih besar daripada 3.1.3 saya mencoba hal-hal seperti:

[[UIDevice currentDevice].systemVersion floatValue]

tetapi tidak berhasil, saya hanya ingin:

if (version > 3.1.3) { }

Bagaimana saya bisa mencapai ini?


5
Catatan Moderator : Seiring waktu, pertanyaan ini menghasilkan lebih dari 30 jawaban. Sebelum menambahkan jawaban baru, pastikan solusi Anda belum disediakan.
Matt

3
Mulai Xcode 7, if #available(iOS 9, *) {}di Swift. Mulai Xcode 9, if (@available(iOS 11, *)) {}secara objektif-c.
Cœur

Jawaban:


1002

Jawaban cepat ...


Pada Swift 2.0, Anda dapat menggunakan #availabledalam ifatau guarduntuk melindungi kode yang seharusnya hanya dijalankan pada sistem tertentu.

if #available(iOS 9, *) {}


Di Objective-C, Anda perlu memeriksa versi sistem dan melakukan perbandingan.

[[NSProcessInfo processInfo] operatingSystemVersion] di iOS 8 dan di atas.

Pada Xcode 9:

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


Jawaban lengkapnya ...

Dalam Objective-C, dan Swift dalam kasus yang jarang terjadi, lebih baik untuk menghindari mengandalkan versi sistem operasi sebagai indikasi kemampuan perangkat atau OS. Biasanya ada metode yang lebih dapat diandalkan untuk memeriksa apakah fitur atau kelas tertentu tersedia.

Memeriksa keberadaan API:

Misalnya, Anda dapat memeriksa apakah UIPopoverControllertersedia di perangkat saat ini menggunakan NSClassFromString:

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

Untuk kelas yang memiliki tautan lemah, aman untuk mengirim pesan ke kelas secara langsung. Khususnya, ini berfungsi untuk kerangka kerja yang tidak secara eksplisit ditautkan sebagai "Diperlukan". Untuk kelas yang hilang, ekspresi bernilai nol, gagal kondisinya:

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

Beberapa kelas, seperti CLLocationManagerdan UIDevice, menyediakan metode untuk memeriksa kemampuan perangkat:

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

Memeriksa keberadaan simbol:

Sangat jarang, Anda harus memeriksa keberadaan konstanta. Ini muncul di iOS 8 dengan pengenalan UIApplicationOpenSettingsURLString, digunakan untuk memuat aplikasi Pengaturan via -openURL:. Nilai tidak ada sebelum iOS 8. Melewati nol ke API ini akan macet, jadi Anda harus berhati-hati untuk memverifikasi keberadaan konstanta terlebih dahulu:

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

Membandingkan dengan versi sistem operasi:

Mari kita asumsikan Anda dihadapkan dengan kebutuhan yang relatif jarang untuk memeriksa versi sistem operasi. Untuk proyek yang menargetkan iOS 8 dan di atasnya, NSProcessInfosertakan metode untuk melakukan perbandingan versi dengan lebih sedikit kemungkinan kesalahan:

- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version

Proyek menargetkan sistem yang lebih tua dapat menggunakan systemVersionpada UIDevice. Apple menggunakannya dalam kode sampel GLSprite mereka .

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

Jika karena alasan apa pun Anda memutuskan itulah systemVersionyang Anda inginkan, pastikan untuk memperlakukannya sebagai string atau Anda berisiko memotong nomor revisi tambalan (mis. 3.1.2 -> 3.1).


161
Ada kasus khusus di mana memeriksa versi sistem dijamin. Sebagai contoh, beberapa kelas dan metode yang bersifat pribadi n 3.x dibuat publik di 4.0, jadi jika Anda hanya memeriksa ketersediaannya, Anda akan mendapatkan hasil yang salah dalam 3.x. Selain itu, cara UIScrollViews menangani skala zoom berubah secara halus di 3.2 dan di atas, jadi Anda perlu memeriksa versi OS untuk memproses hasilnya dengan tepat.
Brad Larson

2
iOS 3.2 tampaknya tidak mengirim -viewWillAppeardalam UISplitViewController. Retas saya adalah untuk menentukan apakah <iOS 4.0, dan mengirimkannya sendiri ke Detail View Controller di Root View's -didSelectRowAtIndexPath.
jww

10
Anda perlu sedikit berhati-hati di sini karena [@"10.0" compare:@"10" options:NSNumericSearch]pengembalian NSOrderedDescending, yang mungkin tidak dimaksudkan sama sekali. (Saya mungkin berharap NSOrderedSame.) Ini setidaknya kemungkinan teoretis.
SK9

Yap, saya baru saja menemukan kasus di mana bug iOS 5 perlu dielakkan. respondsToSelectoret al tidak akan melakukan pekerjaan - harus membandingkan versi.
Hot Licks

2
Dengan diperkenalkannya TVos, ini bahkan menjadi lebih penting. Lihat sebagai TVOS akan mengembalikan 9.0 sementara 9.1 SDK digunakan. Jadi, periksa kelas atau metode (pemilih) adalah cara terbaik, setelah ini Anda harus memeriksa NSFoundationVersionNumberdan hanya jika itu tidak mungkin Anda memeriksa versi sistem 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. Menjaga ini di header yang dapat Anda sertakan di mana diperlukan adalah solusi termudah yang bisa saya pikirkan. Dalam beberapa kasus ini lebih dapat diandalkan daripada memeriksa ketersediaan menggunakan NSClassFromString. Contoh lain adalah di iAd, di mana jika Anda menggunakan ADBannerContentSizeIdentifierPortrait dalam versi sebelum 4.2 Anda akan mendapatkan EXEC_BAD_ACCESS, tetapi ADBannerContentSizeIdentifier320x50 yang sama tidak digunakan setelah 4.1.
Rab

1
Tempat lain yang saya gunakan adalah dengan UIPageViewController dan mengatur gaya ke UIPageViewControllerTransitionStyleScroll di iOS6.
Paul de Lange

7
Ini tidak berfungsi untuk 10-an. Misalnya membandingkan 4.10 dan 4.9 akan memberikan hasil yang salah.
pzulw

7
Seseorang harus sangat berhati-hati saat menggunakan .0nomor opsional . Misalnya SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0.0")memberikan hasil yang salah pada iOS 7.0.
Yan

1
Saya baru saja menguji menempatkan ini dalam file .pch saya dan berfungsi dengan baik (setidaknya membangun dengan Xcode 5)
whyoz

253

Seperti yang disarankan oleh dokumen resmi Apple : Anda dapat menggunakan NSFoundationVersionNumber, dari NSObjCRuntime.hfile header.

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

40
+1 Ini sebenarnya adalah opsi paling aman dan paling akurat di sini.
mxcl

8
Um .. NSFoundationVersionNumber_iOS_6_1tidak ada di iOS 5 SDK.
Kjuly

2
@Kjuly Anda dapat menentukan nomor versi yang hilang dengan sendirinya: github.com/carlj/CJAMacros/blob/master/CJAMacros/CJAMacros.h (lihat baris 102-130)
CarlJ

3
tidak, Anda salah, NSFoundationVersionNumber_iOS_7_0 tidak ada. Tapi yah, kita bisa mendefinisikannya dengan #ifndef NSFoundationVersionNumber_iOS_7_0 #define NSFoundationVersionNumber_iOS_7_0 1047.00 #endif. Untuk menghindari kekacauan seperti itu, saya menggunakan makro SYSTEM_VERSION_LESS_THAN (v) dari yasirmturk
Cœur

7
tidak, tetapi apel akan menambahkan NSFoundationVersionNumber_iOS_8_0di iOS 9. cukup periksa NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1
CarlJ

111

Mulai Xcode 9, di Objective-C :

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

Mulai Xcode 7, di Swift :

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

Untuk versi, Anda dapat menentukan MAJOR, MINOR atau PATCH (lihat http://semver.org/ untuk definisi). Contoh:

  • iOS 11dan iOS 11.0merupakan versi minimal yang sama
  • iOS 10, iOS 10.3, iOS 10.3.1Adalah versi minimal yang berbeda

Anda dapat memasukkan nilai untuk semua sistem tersebut:

  • iOS, macOS, watchOS,tvOS

Contoh kasus nyata diambil dari salah satu pod saya :

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

dokumentasi


Bagaimana ini bisa dibalik di Objective-C atau Swift?
Legoless

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

Dapatkah saya menggunakan guarddi Objective-C bukannya membiarkan blok terbuka dan indentasi dalam elsepernyataan?
Legoless

@Legoless no, cukup gunakan ifblok kosong yang diikuti oleh else.
Cœur

1
Itulah solusi yang saya miliki saat ini, hanya ingin menghindari lekukan yang tidak perlu dan ifblok kosong .
Legoless

45

Ini digunakan untuk memeriksa versi SDK yang kompatibel di Xcode, ini adalah jika Anda memiliki tim besar dengan versi Xcode yang berbeda atau beberapa proyek yang mendukung SDK berbeda yang memiliki kode yang sama:

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

Yang benar-benar Anda inginkan adalah memeriksa versi iOS di perangkat. Anda dapat melakukannya dengan ini:

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

Versi cepat:

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
}

Versi swift saat ini harus menggunakan ini:

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

37

Mencoba:

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
Mengapa tidak membalikkan pesanan di sini dan menyimpan perbandingan, karena @ "3.1.3" dan systemVersion adalah NSStrings? Yaitu: `if ([@" 3.1.3 "bandingkan: [UIDevice currentDevice] .systemVersion options: NSNumericSearch] == NSOrderedDescending); // Versi OS> = 3.1.3 lainnya; // Versi OS <3.1.3`
Rob

3
Melakukan hal itu dapat membuat logika kurang jelas. Namun, operasinya harus setara.
Jonathan Grynspan

1
Perbandingan antara dua bilangan bulat tentunya tidak terlalu mahal.
KPM

Ini benar-benar masalah gaya. Overhead pengiriman pesan akan jauh lebih besar daripada perbandingan integer ekstra.
Jonathan Grynspan

35

Pendekatan yang disukai

Di Swift 2.0 Apple menambahkan pemeriksaan ketersediaan menggunakan sintaks yang jauh lebih nyaman (Baca lebih lanjut di sini ). Sekarang Anda dapat memeriksa versi OS dengan sintaks yang lebih bersih:

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

Ini lebih disukai daripada memeriksa respondsToSelectordll ( Apa yang Baru Di Swift ). Sekarang kompiler akan selalu memperingatkan Anda jika Anda tidak menjaga kode Anda dengan benar.


Pra Swift 2.0

Baru di iOS 8 NSProcessInfomemungkinkan untuk pemeriksaan versi semantik yang lebih baik.

Menyebarkan di iOS 8 dan lebih tinggi

Untuk target penyebaran minimum iOS 8.0 atau lebih tinggi, gunakan NSProcessInfo operatingSystemVersionatau isOperatingSystemAtLeastVersion.

Ini akan menghasilkan yang berikut:

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

Menyebarkan di iOS 7

Untuk target penyebaran minimum iOS 7.1 atau di bawahnya, gunakan bandingkan dengan NSStringCompareOptions.NumericSearchpada UIDevice systemVersion.

Ini akan menghasilkan:

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

Lebih banyak membaca di NSHipster .


9

Saya selalu menyimpannya di file Constants.h saya:

#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)

Bagus. Lebih baik menempatkan ini dalam .pchfile Proyek XCode Anda
Vaibhav Jhaveri

1
Saya menempatkan semua konstanta saya di Constants.hfile saya yang diimpor dalam pchfile saya .
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 Periode bukanlah titik desimal dalam versi dan relevan. Jawaban Anda tidak mengabaikan periode, Itu akan gagal jika itu terjadi. Dalam versi setiap elemen dipisahkan periode adalah angka penuh. Contoh: '1.23.45' lebih besar dari '1.2.345' karena elemen kedua '23' lebih besar dari '2'. Jika Anda akan menghilangkan periode itu akan menjadi angka yang sama.
Andres Canella

6

Dengan kelas Versi yang terkandung dalam proyek versi nv-ios (Lisensi Apache, Versi 2.0), mudah untuk mendapatkan dan membandingkan versi iOS. Contoh kode di bawah ini membuang versi iOS dan memeriksa apakah versi lebih besar dari atau sama dengan 6.0.

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

Halaman Proyek: nv-ios-versi
TakahikoKawasaki / nv-ios-version

Blog: Dapatkan dan bandingkan versi iOS saat runtime dengan kelas Versi
Dapatkan dan bandingkan versi iOS saat runtime dengan kelas Versi


5

Cara baru untuk memeriksa versi sistem menggunakan swift Forget [[UIDevice currentDevice] systemVersion] dan NSFoundationVersionNumber.

Kita dapat menggunakan NSProcessInfo -isOperatingSystemAtLeastVersion

     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

Secara umum lebih baik untuk bertanya apakah suatu objek dapat melakukan pemilih yang diberikan, daripada memeriksa nomor versi untuk memutuskan apakah harus hadir.

Ketika ini bukan opsi, Anda harus sedikit berhati-hati di sini karena [@"5.0" compare:@"5" options:NSNumericSearch]pengembalian NSOrderedDescendingyang mungkin tidak dimaksudkan sama sekali; Saya mungkin berharap di NSOrderedSamesini. Setidaknya ini adalah kekhawatiran teoretis, yang layak dipertahankan menurut saya.

Juga patut dipertimbangkan adalah kemungkinan input versi buruk yang tidak dapat dibandingkan secara masuk akal. Apple memasok tiga konstanta yang telah ditentukan NSOrderedAscending, NSOrderedSamedan NSOrderedDescendingtetapi saya bisa memikirkan penggunaan untuk beberapa hal yang disebut NSOrderedUnorderedjika saya tidak dapat membandingkan dua hal dan saya ingin mengembalikan nilai yang menunjukkan ini.

Terlebih lagi, bukan tidak mungkin bahwa suatu hari Apple akan memperluas tiga konstanta yang telah ditentukan sebelumnya untuk memungkinkan berbagai nilai pengembalian, membuat perbandingan menjadi != NSOrderedAscendingtidak bijaksana.

Dengan ini, pertimbangkan kode berikut.

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
}

Di mana tentu saja, NSFoundationVersionNumber_iOS_6_1harus diubah agar berlaku untuk versi iOS yang ingin Anda periksa. Apa yang saya tulis sekarang mungkin akan banyak digunakan ketika menguji apakah perangkat menjalankan iOS7 atau versi sebelumnya.


4

sedikit terlambat ke pesta tetapi mengingat iOS 8.0 di luar sana ini mungkin relevan:

jika Anda dapat menghindari menggunakan

[[UIDevice currentDevice] systemVersion]

Alih-alih memeriksa keberadaan metode / kelas / apa pun.

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

Saya menemukan itu berguna untuk manajer lokasi di mana saya harus memanggil requestWhenInUseAuthorization for iOS 8.0 tetapi metode ini tidak tersedia untuk iOS <8


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

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

3

Saya tahu ini adalah pertanyaan lama, tetapi seseorang seharusnya menyebutkan makro waktu kompilasi Availability.h. Semua metode lain di sini adalah solusi runtime, dan tidak akan berfungsi dalam file header, kategori kelas, atau definisi ivar.

Untuk situasi ini, gunakan

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

h / t jawaban ini


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

Kemudian tambahkan kondisi if sebagai berikut: -

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

2

Ada versi seperti 7.0 atau 6.0.3, jadi kita dapat dengan mudah mengkonversi versi menjadi angka untuk dibandingkan. jika versinya seperti 7.0, cukup tambahkan ".0" lainnya dan ambil nilai numeriknya.

 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];

Untuk 6.0.0

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

untuk 7.0

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

hanya menghilangkan titik desimal adalah pendekatan yang salah. pertimbangkan komponen yang panjangnya lebih dari 1 karakter, mis 6.1.10. maka algoritma ini akan menghasilkan 6110 > 700, yang tidak benar.
ardnew

Saya mengerti apel buruk dalam meluncurkan versi baru tetapi di sebagian besar nomor kedua versi waktu tidak pernah melampaui 5, jadi 10 tidak dipertanyakan. Ini adalah pendekatan adhoc jadi jika menangani kasus untuk 2 komponen Anda dapat memodifikasinya untuk menangani empat kasus aswel jika Anda ingin melakukannya secara manual. Bagaimanapun pendekatan ini dikomentari pada saat iOS6 atau 7. iOS 9 dan 10 memiliki cara yang lebih baik untuk memeriksanya yaitu # tersedia.
NaXir

2

Coba kode di bawah ini:

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


1

Sebagai variasi dari solusi yasimturks, saya mendefinisikan satu fungsi dan beberapa nilai enum alih-alih lima makro. Saya merasa lebih elegan, tapi itu masalah selera.

Pemakaian:

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

file .h:

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

BOOL systemVersion(Comparison test, NSString* version);

file .m:

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

Anda harus menambahkan awalan aplikasi Anda ke nama-nama, terutama untuk Comparisonjenisnya.


1

Menggunakan cara yang disarankan yang direferensikan ... jika tidak ada definisi dalam file header, Anda selalu bisa mendapatkan versión mencetaknya di konsol dengan perangkat versión IOS yang diinginkan.

- (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

Solusi untuk memeriksa versi iOS di Swift

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

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

Con dari solusi ini: itu hanya praktik buruk untuk memeriksa terhadap nomor versi OS, apa pun cara Anda melakukannya. Seseorang seharusnya tidak pernah ketergantungan kode dengan cara ini, selalu memeriksa fitur, kemampuan atau keberadaan kelas. Pertimbangkan ini; Apple dapat merilis versi kelas yang kompatibel ke belakang, jika mereka melakukannya maka kode yang Anda sarankan tidak akan pernah menggunakannya karena logika Anda mencari nomor versi OS dan BUKAN keberadaan kelas.

( Sumber informasi ini )

Solusi untuk memeriksa keberadaan kelas di Swift

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

Jangan gunakan if (NSClassFromString("UIAlertController") == nil)karena berfungsi dengan benar pada simulator iOS menggunakan iOS 7.1 dan 8.2, tetapi jika Anda menguji pada perangkat nyata menggunakan iOS 7.1, Anda sayangnya akan melihat bahwa Anda tidak akan pernah melewati bagian lain dari potongan kode.


Mengapa harus memilih? Solusi ini berfungsi sempurna menggunakan Swift dan versi iOS apa pun. Terutama pemeriksaan keberadaan kelas yang sempurna.
King-Wizard

1
#define IsIOS8 (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)

0

Versi yang lebih umum dalam Obj-C ++ 11 (Anda mungkin bisa mengganti beberapa hal ini dengan fungsi NSString / C, tetapi ini kurang bertele-tele. Ini memberi Anda dua mekanisme. SplitSystemVersion memberi Anda array semua bagian yang berguna jika Anda hanya ingin mengaktifkan versi utama (mis switch([self splitSystemVersion][0]) {case 4: break; case 5: break; }.).

#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;bahkan tidak bisa dikompilasi.
Pang

0

Contoh cepat yang benar-benar berfungsi:

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

Jangan gunakan NSProcessInfo karena tidak berfungsi di bawah 8.0, jadi itu cukup berguna sampai 2016


0

Ini adalah versi cepat:

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

Pemakaian:

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

Saya pikir Versi harus iOSVersion di baris 3-6 seperti 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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.