IOS वर्जन कैसे चेक करें?


848

मैं जांचना चाहता हूं कि क्या iOSडिवाइस का संस्करण 3.1.3 मेरे द्वारा की गई चीजों की तुलना में अधिक है :

[[UIDevice currentDevice].systemVersion floatValue]

लेकिन यह काम नहीं करता है, मुझे बस एक चाहिए:

if (version > 3.1.3) { }

इसे कैसे प्राप्त किया जा सकता है?


5
मॉडरेटर नोट : समय के साथ, इस सवाल ने 30 से अधिक उत्तरों को अर्जित किया है। एक नया उत्तर जोड़ने से पहले, सुनिश्चित करें कि आपका समाधान पहले से ही प्रदान नहीं किया गया है।
मैट

3
if #available(iOS 9, *) {}स्विफ्ट में , Xcode 7 शुरू करना । Xcode 9 को, if (@available(iOS 11, *)) {}उद्देश्य-सी में शुरू करना।
C --ur

जवाबों:


1001

त्वरित उत्तर…


स्विफ्ट 2.0 के रूप में, आप #availableएक ifया guardकोड को बचाने के लिए उपयोग कर सकते हैं जो केवल कुछ सिस्टम पर चलाया जाना चाहिए।

if #available(iOS 9, *) {}


ऑब्जेक्टिव-सी में, आपको सिस्टम संस्करण की जांच करने और तुलना करने की आवश्यकता है।

[[NSProcessInfo processInfo] operatingSystemVersion] iOS 8 और इसके बाद के संस्करण में।

Xcode 9 के रूप में:

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


पूरा जवाब…

उद्देश्य-सी, और दुर्लभ मामलों में स्विफ्ट में, डिवाइस या ओएस क्षमताओं के संकेत के रूप में ऑपरेटिंग सिस्टम संस्करण पर भरोसा करने से बचना बेहतर है। आमतौर पर यह जांचने का एक अधिक विश्वसनीय तरीका है कि क्या कोई विशेष सुविधा या वर्ग उपलब्ध है।

एपीआई की उपस्थिति के लिए जाँच:

उदाहरण के लिए, यदि आप UIPopoverControllerवर्तमान डिवाइस पर उपलब्ध है , तो आप जाँच कर सकते हैं NSClassFromString:

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

कमजोर रूप से जुड़े वर्गों के लिए, सीधे कक्षा को संदेश देना सुरक्षित है। विशेष रूप से, यह चौखटे के लिए काम करता है जो स्पष्ट रूप से "आवश्यक" के रूप में जुड़ा नहीं है। लापता कक्षाओं के लिए, अभिव्यक्ति शून्य का मूल्यांकन करती है, स्थिति को विफल करती है:

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

कुछ वर्ग, जैसे CLLocationManagerऔर UIDevice, उपकरण क्षमताओं की जांच करने के तरीके प्रदान करते हैं:

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

प्रतीकों की उपस्थिति के लिए जाँच:

कभी-कभी, आपको एक स्थिरांक की उपस्थिति के लिए जांच करनी चाहिए। यह आईओएस 8 में पेश UIApplicationOpenSettingsURLStringकिया गया था, के माध्यम से सेटिंग्स ऐप को लोड करने के लिए उपयोग किया जाता है -openURL:। IOS से पहले मान मौजूद नहीं था। इस एपीआई के लिए निएल पास करना दुर्घटनाग्रस्त हो जाएगा, इसलिए आपको निरंतर अस्तित्व के सत्यापन को ध्यान में रखना होगा:

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

ऑपरेटिंग सिस्टम संस्करण के खिलाफ तुलना:

मान लेते हैं कि ऑपरेटिंग सिस्टम संस्करण की जाँच करने के लिए आपको अपेक्षाकृत दुर्लभ आवश्यकता का सामना करना पड़ रहा है। IOS 8 और इसके बाद के संस्करण की परियोजनाओं के लिए, NSProcessInfoत्रुटि की कम संभावना वाले संस्करण की तुलना करने के लिए एक विधि शामिल है:

- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version

पुराने सिस्टम को लक्षित करने की परियोजनाओं का उपयोग कर सकते systemVersionपर UIDevice। Apple अपने GLSprite नमूना कोड में इसका उपयोग करता है ।

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

यदि जो भी कारण आप तय करते हैं कि systemVersionआप क्या चाहते हैं, तो इसे एक स्ट्रिंग के रूप में व्यवहार करना सुनिश्चित करें या आप पैच संशोधन संख्या को कम करने का जोखिम उठाते हैं (उदाहरण। 3.1.2 -> 3.1)।


161
ऐसे विशिष्ट मामले हैं जहां सिस्टम संस्करण के लिए जाँच की जाती है। उदाहरण के लिए, कुछ वर्गों और विधियों जो निजी n 3.x थे, उन्हें 4.0 में सार्वजनिक किया गया था, इसलिए यदि आप बस उनकी उपलब्धता की जांच करते हैं तो आपको 3.x में गलत परिणाम मिलेगा। इसके अतिरिक्त, जिस तरह से UIScrollViews ज़ूम 3.2 को बढ़ाता है, वह तेजी से 3.2 और इसके बाद के संस्करण में बदल गया है, इसलिए आपको परिणामों को उचित रूप से संसाधित करने के लिए ओएस संस्करणों की जांच करने की आवश्यकता होगी।
ब्रैड लार्सन

2
iOS 3.2 -viewWillAppearएक में भेजने के लिए प्रकट नहीं होता है UISplitViewController। मेरा हैक यह निर्धारित करने के लिए है कि <iOS 4.0, और इसे विस्तार दृश्य नियंत्रक को स्वयं रूट दृश्य में भेजें -didSelectRowAtIndexPath
jww

10
यहां आपको थोड़ा सावधान रहने की जरूरत है क्योंकि [@"10.0" compare:@"10" options:NSNumericSearch]रिटर्न NSOrderedDescending, जो अच्छी तरह से बिल्कुल भी नहीं हो सकता है। (मैं उम्मीद कर सकता हूं NSOrderedSame।) यह कम से कम एक सैद्धांतिक संभावना है।
SK9

हां, मुझे अभी एक मामले का सामना करना पड़ा जहां एक iOS 5 बग को दरकिनार करने की आवश्यकता थी। respondsToSelectorएट अल काम नहीं करेगा - संस्करणों की तुलना करना होगा।
हॉट लक्स

2
TVos की शुरुआत के साथ यह और भी महत्वपूर्ण हो गया है। टीवीएस के रूप में देखें 9.0 लौटेंगे जबकि 9.1 एसडीके का उपयोग किया गया है। इसलिए क्लास या मेथड (चयनकर्ता) सबसे अच्छा तरीका है, इसके बाद आपको चेक करना चाहिए NSFoundationVersionNumberऔर केवल तभी यह संभव नहीं है जब आपको सिस्टम वर्जन को चेक करना चाहिए 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। इसे एक हेडर में रखते हुए जिसे आप शामिल कर सकते हैं जहां जरूरत है सबसे आसान समाधान मैं सोच सकता हूं। कई मामलों में यह NSClassFromString का उपयोग करके उपलब्धता की जाँच करने से अधिक विश्वसनीय है। एक अन्य उदाहरण आईएडी में है, जहां अगर आप 4.2 से पहले एक संस्करण में ADBannerContentSizeIdentifierPortrait का उपयोग करते हैं, तो आपको EXEC_BAD_ACCESS मिलेगा, लेकिन 4.1 के बाद ADBannerContentSizeIdentifier320x50 के बराबर है।
राब

1
एक अन्य जगह मैं इसका उपयोग UIPageViewController के साथ कर रहा हूं और iOS6 में UIPageViewControllerTransitionStyleScroll को स्टाइल सेट कर रहा हूं।
पॉल डे लैंग

7
यह 10s के लिए काम नहीं करता है। उदाहरण के लिए 4.10 और 4.9 की तुलना करना गलत परिणाम देगा।
pululw

7
वैकल्पिक .0संख्याओं का उपयोग करते समय एक बहुत सावधान रहना चाहिए । उदाहरण के लिए SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0.0")iOS 7.0 पर गलत परिणाम देता है।
यान

1
मैंने इसे केवल अपनी .pch फ़ाइल में डालने का परीक्षण किया और यह बढ़िया काम करता है (Xcode 5 के साथ कम से कम निर्माण)
Whyoz

253

जैसा कि आधिकारिक Apple डॉक्स ने सुझाव दिया है : आप हेडर फ़ाइल NSFoundationVersionNumberसे, का उपयोग कर सकते हैं NSObjCRuntime.h

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

40
+1 यह वास्तव में यहां सबसे सुरक्षित और सटीक विकल्प है।
mxcl

8
उम .. NSFoundationVersionNumber_iOS_6_1आईओएस 5 एसडीके में मौजूद नहीं है।
काजुल

2
@ किजुल आप अपने स्वयं के द्वारा गायब किए गए संस्करण को परिभाषित कर सकते हैं: github.com/carlj/CJAMacros/blob/master/CJAMacros/CJAMacros.h (लाइन 102.830 पर एक नज़र डालें)
कार्लजे सेप

3
नहीं, आप गलत हैं, NSFoundationVersionNumber_iOS_7_0 मौजूद नहीं है। लेकिन ठीक है, हम इसे परिभाषित कर सकते हैं #ifndef NSFoundationVersionNumber_iOS_7_0 #define NSFoundationVersionNumber_iOS_7_0 1047.00 #endif। ऐसे ही खिलवाड़ से बचने के लिए, मैं SYSTEM_VERSION_LESS_THAN (v) मैक्रो के साथ yasirmturk से चला गया
कोयूर

7
नहीं, लेकिन Apple NSFoundationVersionNumber_iOS_8_0iOS 9 में जोड़ देगा। बस के लिए जाँच करें NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1
कार्ल जेप

111

उद्देश्य-सी में Xcode 9 शुरू करना :

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

स्विफ्ट में Xcode 7 शुरू करना :

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

संस्करण के लिए, आप MAJOR, MINOR या PATCH ( परिभाषाओं के लिए http://semver.org/ देखें ) निर्दिष्ट कर सकते हैं । उदाहरण:

  • iOS 11और iOS 11.0वही न्यूनतम संस्करण हैं
  • iOS 10, iOS 10.3, iOS 10.3.1अलग न्यूनतम संस्करण हैं

आप उन प्रणालियों में से किसी के लिए मानों का इनपुट कर सकते हैं:

  • iOS, macOS, watchOS,tvOS

मेरी एक फली से लिया गया वास्तविक मामला उदाहरण :

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

प्रलेखन


इसे ऑब्जेक्टिव-सी या स्विफ्ट में कैसे बदला जा सकता है?
लेगलेस सेप

@Legolessif (...) {} else { ... }
कोयूर

क्या मैं guardब्लॉक-ओपन और elseस्टेटमेंट में इंडेंट छोड़ने के बजाय ऑब्जेक्टिव-सी में इस्तेमाल कर सकता हूं ?
लेगलेस

@Legoless नहीं, बस एक खाली ifब्लॉक का उपयोग करें a else
कोयूर

1
वर्तमान में मेरे पास इसका समाधान है, बस अनावश्यक खरोज और खाली ifब्लॉकों से बचना चाहता था ।
15

45

इसका उपयोग Xcode में SDK के संगत संस्करण की जांच करने के लिए किया जाता है, यह है यदि आपके पास Xcode या विभिन्न परियोजनाओं के विभिन्न संस्करणों के साथ एक बड़ी टीम है जो विभिन्न SDK का समर्थन करते हैं जो समान कोड साझा करते हैं:

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

आप वास्तव में क्या चाहते हैं डिवाइस पर आईओएस संस्करण की जांच करना है। आप ऐसा कर सकते हैं:

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

स्विफ्ट संस्करण:

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
}

स्विफ्ट के वर्तमान संस्करणों को इसका उपयोग करना चाहिए:

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

37

प्रयत्न:

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
यहां आदेश को उल्टा क्यों न करें और एक तुलना को बचाएं, क्योंकि दोनों @ "3.1.3" और सिस्टमविज़न एनएसएसट्रेस हैं? Ie: `if ([@" 3.1.3 "तुलना करें: [UIDevice currentDevice] .systemVersion विकल्प: NSNumericSearch] == NSOrderedDescending); // OS संस्करण> = 3.1
रोब

3
ऐसा करने से तर्क कम स्पष्ट हो सकता है। हालांकि, ऑपरेशन समकक्ष होना चाहिए।
जोनाथन ग्रिप्सन

1
दो पूर्णांकों के बीच तुलना निश्चित रूप से बहुत महंगी नहीं है।
केपीएम जूल

यह वास्तव में शैली की बात है। संदेश प्रेषण का ओवरहेड अतिरिक्त पूर्णांक तुलना से बहुत आगे निकल जाएगा।
जोनाथन ग्रियर्सन 14

35

पसंदीदा दृष्टिकोण

स्विफ्ट 2.0 में Apple ने अधिक सुविधाजनक सिंटैक्स का उपयोग करके उपलब्धता की जाँच की ( यहाँ और पढ़ें )। अब आप एक क्लीनर सिंटैक्स के साथ ओएस संस्करण की जांच कर सकते हैं:

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

यह चेकिंग respondsToSelectorआदि के लिए पसंदीदा है ( व्हाट्स न्यू इन स्विफ्ट )। यदि आप अपने कोड को ठीक से रख नहीं रहे हैं तो अब कंपाइलर आपको हमेशा चेतावनी देगा।


प्री स्विफ्ट 2.0

IOS 8 में नया NSProcessInfoबेहतर अर्थ वर्जनिंग चेक के लिए अनुमति दे रहा है।

IOS 8 और अधिक पर निर्भर करता है

IOS 8.0 या इसके बाद के संस्करण के न्यूनतम परिनियोजन लक्ष्यों के लिए , उपयोग करें NSProcessInfo operatingSystemVersionयाisOperatingSystemAtLeastVersion

यह निम्नलिखित होगा:

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

IOS 7 पर तैनात

की न्यूनतम तैनाती लक्ष्यों के लिए आईओएस 7.1 या नीचे, के साथ तुलना का उपयोग NSStringCompareOptions.NumericSearchपर UIDevice systemVersion

इससे उपज मिलेगी:

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 में अधिक पढ़ना ।


9

मैं हमेशा उन लोगों को अपनी कॉन्स्टेंट.एच फाइल में रखता हूं:

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

महान। इसे .pchअपने XCode प्रोजेक्ट की फाइल में रखने के लिए बेहतर है
वैभव झावेरी

1
मैं अपने सभी स्थिरांक को अपनी Constants.hफ़ाइल में रखता हूं जो मेरी pchफ़ाइल में आयात किया गया है ।
सेगेव

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 पीरियड्स वर्जनिंग में दशमलव पॉइंट नहीं हैं और प्रासंगिक हैं। आपका उत्तर पीरियड्स को नजरअंदाज नहीं करता है, अगर यह होता तो यह विफल हो जाता। संस्करण में प्रत्येक अवधि अलग तत्व एक पूर्ण संख्या है। Ex: '1.23.45' '1.2.345' से बड़ा है क्योंकि दूसरा तत्व '23' '2' से बड़ा है। अगर आप पीरियड्स को खत्म कर देंगे तो यह एक ही नंबर होगा।
एंड्रेस कैनेला जूल

6

संस्करण वर्ग के साथ जो nv-ios- संस्करण परियोजना (Apache लाइसेंस, संस्करण 2.0) में निहित है , iOS संस्करण को प्राप्त करना और तुलना करना आसान है। नीचे एक उदाहरण कोड आईओएस संस्करण को डंप करता है और जांचता है कि संस्करण 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.
}

प्रोजेक्ट पेज: nv-ios-version
TakahikoKawasaki / nv-ios-version

ब्लॉग: संस्करण वर्ग के साथ रनटाइम पर iOS संस्करण
प्राप्त करें और तुलना करें और संस्करण वर्ग के साथ रनटाइम पर iOS संस्करण की तुलना करें


5

स्विफ्ट फोर् ट [[UIDevice currentDevice] systemVersion] और NSFoundationVersionNumber का उपयोग करके सिस्टम संस्करण की जांच करने का नया तरीका।

हम 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

सामान्य तौर पर यह पूछना बेहतर है कि क्या कोई ऑब्जेक्ट किसी दिए गए चयनकर्ता को कर सकता है, बजाय यह तय करने के लिए कि उसे मौजूद होना चाहिए या नहीं।

जब यह एक विकल्प नहीं है, तो आपको यहां थोड़ा सावधान रहने की आवश्यकता है क्योंकि [@"5.0" compare:@"5" options:NSNumericSearch]रिटर्न NSOrderedDescendingजो अच्छी तरह से बिल्कुल भी इरादा नहीं हो सकता है; मैं NSOrderedSameयहाँ उम्मीद कर सकता हूँ । यह कम से कम एक सैद्धांतिक चिंता है, जो मेरी राय में बचाव करने लायक है।

इसके अलावा विचार के लायक एक खराब संस्करण इनपुट की संभावना है जिसकी तुलना में यथोचित नहीं किया जा सकता है। Apple तीन पूर्वनिर्धारित स्थिरांक की आपूर्ति करता है NSOrderedAscending, NSOrderedSameऔर NSOrderedDescendingलेकिन मैं किसी चीज के लिए उपयोग के बारे में सोच सकता हूं जिसे NSOrderedUnorderedउस घटना में कहा जाता है जिसकी मैं दो चीजों की तुलना नहीं कर सकता हूं और मैं यह इंगित करते हुए एक मूल्य वापस करना चाहता हूं।

क्या अधिक है, यह असंभव नहीं है कि ऐप्पल किसी दिन अपने तीन पूर्वनिर्धारित स्थिरांक का विस्तार करेगा, विभिन्न प्रकार के रिटर्न मानों की अनुमति देगा, जिससे तुलना एक != NSOrderedAscendingनासमझी होगी।

इसके साथ ही कहा गया, निम्नलिखित कोड पर विचार करें।

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
}

जहाँ निश्चित रूप से, NSFoundationVersionNumber_iOS_6_1उस iOS संस्करण के लिए लागू किया जाना चाहिए जिसे आप जाँचना चाहते हैं। अब मैंने जो लिखा है, उसका परीक्षण करते समय शायद बहुत उपयोग किया जाएगा यदि कोई उपकरण iOS7 या पिछले संस्करण पर चल रहा है।


4

पार्टी के लिए थोड़ा देर से लेकिन आईओएस 8.0 की रोशनी में यह प्रासंगिक हो सकता है:

यदि आप उपयोग करने से बच सकते हैं

[[UIDevice currentDevice] systemVersion]

इसके बजाय एक विधि / वर्ग / जो कुछ भी हो के अस्तित्व की जांच करें।

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

मुझे यह स्थान प्रबंधक के लिए उपयोगी लगा, जहां मुझे iOS 8.0 के लिए requestWhenInUseAuthorization को कॉल करना है, लेकिन यह विधि iOS <8 के लिए उपलब्ध नहीं है



3

मुझे पता है कि यह एक पुराना सवाल है, लेकिन किसी को संकलन-समय के मैक्रोज़ का उल्लेख करना चाहिए था Availability.h। यहाँ अन्य सभी विधियाँ रनटाइम सॉल्यूशन हैं, और हेडर फ़ाइल, क्लास श्रेणी या आइवर परिभाषा में काम नहीं करेंगी।

इन स्थितियों के लिए, का उपयोग करें

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

h / t इस उत्तर


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

फिर एक निम्न शर्त जोड़ें:

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

2

7.0 या 6.0.3 जैसे संस्करण हैं, इसलिए हम तुलना करने के लिए बस वर्जन को न्यूमेरिक्स में बदल सकते हैं। यदि संस्करण 7.0 जैसा है, तो बस इसे एक और ".0" संलग्न करें और फिर इसका संख्यात्मक मान लें।

 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 के लिए

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

7.0 के लिए

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

केवल दशमलव बिंदुओं को हटाना गलत दृष्टिकोण है। एक घटक पर विचार करें जो 1 से अधिक वर्ण लंबा है, जैसे 6.1.10। तब यह एल्गोरिथ्म निकलेगा 6110 > 700, जो सही नहीं है।
२१

मैं समझता हूं कि नए संस्करणों को चालू करने में सेब खराब है, लेकिन अधिकांश समय में संस्करण की दूसरी संख्या 5 से आगे कभी नहीं गई, इसलिए 10 प्रश्न से बाहर है। यह एक एडहॉक दृष्टिकोण है, इसलिए यदि यह 2 घटकों के लिए मामला संभालता है, तो आप इसे चार मामले को संभालने के लिए संशोधित कर सकते हैं यदि आप मैन्युअल रूप से करना चाहते हैं। किसी भी तरह इस दृष्टिकोण पर iOS6 या 7. iOS 9 और 10 के समय टिप्पणी की गई थी, इसकी जाँच के कई बेहतर तरीके हैं अर्थात # उपलब्ध।
NaXir

2

नीचे दिए गए कोड का प्रयास करें:

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


1

यासिमटर्क समाधान की भिन्नता के रूप में, मैंने पांच मैक्रोज़ के बजाय एक फ़ंक्शन और कुछ एनम मानों को परिभाषित किया। मुझे यह अधिक सुरुचिपूर्ण लगता है, लेकिन यह स्वाद का मामला है।

उपयोग:

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

.h फ़ाइल:

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

BOOL systemVersion(Comparison test, NSString* version);

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

आपको अपने ऐप के उपसर्ग को नामों में जोड़ना चाहिए, विशेष रूप से Comparisonटाइप करने के लिए ।


1

संदर्भित अनुशंसित तरीके का उपयोग करते हुए ... यदि शीर्ष लेख फ़ाइलों में कोई परिभाषा नहीं है, तो आप हमेशा वांछित IOS छद्म के एक उपकरण के साथ कंसोल पर इसे मुद्रित करने वाला छद्म प्राप्त कर सकते हैं।

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

स्विफ्ट में आईओएस संस्करण की जांच के लिए समाधान

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

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

इस समाधान का कॉन्न: यह ओएस संस्करण संख्याओं के खिलाफ जांच करने के लिए बस बुरा अभ्यास है, चाहे आप इसे कैसे भी करें। इस तरह से किसी को हार्ड कोड निर्भरता कभी नहीं होनी चाहिए, हमेशा सुविधाओं, क्षमताओं या किसी वर्ग के अस्तित्व की जांच करें। इस पर विचार करो; Apple किसी वर्ग का एक पश्चगामी संगत संस्करण जारी कर सकता है, अगर उन्होंने ऐसा किया तो आपके द्वारा सुझाया गया कोड कभी भी इसका उपयोग नहीं करेगा क्योंकि आपका तर्क OS संस्करण संख्या के लिए दिखता है और वर्ग के अस्तित्व को नहीं।

( इस जानकारी का स्रोत )

स्विफ्ट में वर्ग के अस्तित्व की जाँच के लिए समाधान

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

if (NSClassFromString("UIAlertController") == nil)IOS 7.1 और 8.2 का उपयोग करके iOS सिम्युलेटर पर सही तरीके से काम करने के कारण इसका उपयोग न करें , लेकिन यदि आप iOS 7.1 का उपयोग करके किसी वास्तविक डिवाइस पर परीक्षण करते हैं, तो आप दुर्भाग्य से नोटिस करेंगे कि आप कोड स्निपेट के दूसरे भाग से कभी नहीं गुजरेंगे।


वोटिंग में कमी क्यों? यह समाधान स्विफ्ट और किसी भी आईओएस संस्करण का उपयोग करके पूरी तरह से काम करता है। विशेषकर वर्ग के अस्तित्व की जाँच एकदम सही है।
राजा-जादूगर

1
#define IsIOS8 (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)

0

Obj-C ++ 11 में एक और अधिक सामान्य संस्करण (आप शायद इस सामान को NSString / C फ़ंक्शन के साथ बदल सकते हैं, लेकिन यह कम क्रिया है। इससे आपको दो तंत्र मिलते हैं। विभाजन प्रणालीविस्तार आपको सभी भागों की एक सरणी देता है जो उपयोगी है यदि आप केवल प्रमुख संस्करण (जैसे 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;संकलन भी नहीं कर सकते।
पैंग

0

स्विफ्ट उदाहरण जो वास्तव में काम करता है:

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 का उपयोग न करें क्योंकि यह 8.0 के तहत काम नहीं करता है, इसलिए 2016 तक इसकी बहुत बेकार है


0

यहाँ एक तेज संस्करण है:

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

उपयोग:

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

मुझे लगता है कि संस्करण 3-6 लाइन में iOSVersion होना चाहिए 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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.