2012-06-15 10 views
8

मैं जैसे कुछ परियोजनाओं कुछ में देखा है:कैसे पता चलेगा कि मैक ओएस ऐप किस पर चल रहा है?

#if ..... 
    code... 
#endif 

लेकिन मैं यह अब नहीं मिल सकता है ...
के उदाहरण के लिए कहते हैं, अगर एप्लिकेशन 10.8 पर चल रहा है एप्लिकेशन 1 काम करता है चलो , अगर ऐप अन्य चीज नहीं करता है। यह जांचने के लिए कोड क्या है कि यह 10.8 पर चल रहा है या नहीं?
धन्यवाद।

+0

मैंने त्वरित जांच की, और यह उत्तर आपकी मदद कर सकता है: http://stackoverflow.com/questions/157759/how-can-i-determine-the-running-mac-os-x-version-programmatically – CBredlow

+5

एक सीपीपी # परिभाषित/# यदि आपका दोस्त यहां नहीं है। यह एक * संकलन * स्विच है (उदाहरण के लिए कौन सा मंच/सुविधा * लक्षित * है)। –

+0

#if .... #endif एक प्रीप्रोसेसर है जो संकलन समय पर चलता है, मैं इसका उपयोग dev, qa (test) और रिलीज़ के बीच निर्धारित करने के लिए करता हूं। – Popeye

उत्तर

23

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

उदाहरण के लिए, यदि ऐप्पल मैक ओएस एक्स 10.9 में मैजिक होलोग्राम क्लास पेश करता है जिसे आप उपयोग करना चाहते हैं, तो आप यह जांच नहीं सकते कि उपयोगकर्ता मैक ओएस एक्स 10.9 चला रहा है या नहीं। इसके बजाए, आप जांचें कि MagicHologram क्लास उपलब्ध है या नहीं। यदि ऐसा है, तो आप इसका उपयोग कर सकते हैं। यदि नहीं, तो यह उपलब्ध नहीं है। इससे कोई फर्क नहीं पड़ता कि क्यों। शायद वे 10.8 चल रहे हैं। लेकिन हो सकता है कि यह पांच साल बाद हो, और ऐप्पल ने MagicHologram क्लास को पूरी तरह से छोड़ने का फैसला किया।

(इसके अलावा, ध्यान रखें कि आप HologramKit, पुस्तकालय कि MagicHologram वर्ग प्रदान करता है करने के लिए कमजोर कड़ी नहीं करनी में रहते हैं।)

इसी तरह, अगर वे एक नई विधि NSString करने के बजाय ओएस जाँच के परिचय संस्करण जो आप जांचेंगे कि एनएसएसटींग नई विधि के बारे में जानता है या नहीं।

उस ने कहा, NSApplication.h में एक बाहरी स्थिरांक शामिल है जिसे NSAppKitVersionNumber कहा जाता है। आप इसकी तुलना NSAppKitVersionNumber10_7 जैसे स्थिरांक से कर सकते हैं (यह ध्यान दिया जाना चाहिए) संख्या 1138, 10.7 नहीं है।केवल कुछ ही जगहें उचित हैं, जहां ज्यादातर कक्षाएं निजी और अनियंत्रित थीं लेकिन दस्तावेज होने से पहले और एसडीके के सार्वजनिक हिस्सों का हिस्सा बनने से पहले बड़े बदलाव हुए। साथ ही, यह उपयोगी हो सकता है यदि आप एक विशिष्ट बग से बचना चाहते हैं जिसे बाद में तय किया गया है।

संक्षेप में

:

  1. अलग अलग वर्गों और विधियों, जो आपके मामलों के 99.44% को कवर करना चाहिए का पता लगाने।
  2. उन मामलों को कवर करने के लिए NSAppKitVersionNumber और NSAppKitVersionNumber10_7 का उपयोग करें जहां कक्षा या विधि का पता लगाना आपके लिए झूठ बोलता है।
  3. उन पहले दो बिंदुओं में सभी सामान्य मामले शामिल हैं। आपको आगे नहीं जाना चाहिए। लेकिन अगर आपके पास मानवीय संस्करण के आधार पर व्यवहार होना चाहिए, तो नीचे दिए गए अर्नर्नर्ट के उत्तर को देखें। यह उन्हें पाने का सबसे अच्छा तरीका है।
  4. operatingSystemVersionString का उपयोग न करें, जो विशेष रूप से पार्सिंग के लिए सुरक्षित नहीं है।

संदर्भ/अधिक जानकारी:

  • SDK Compatibility Guide "इस दस्तावेज़ पढ़ें अगर आप चाहते हैं या किसी विशेष संस्करण या iOS या मैक ओएस एक्स के एक से अधिक संस्करण को लक्षित करने के लिए आपके आवेदन"
    • Using SDK-Based Development बताता है कि एक ऑपरेटिंग सिस्टम के कई संस्करणों पर चलने के समर्थन में कमजोर रूप से जुड़े वर्गों, विधियों और कार्यों का उपयोग कैसे करें।
-4

आप इस तरह OS संस्करण प्राप्त कर सकते हैं:

NSString *version = [[NSProcessInfo processInfo] operatingSystemVersionString]; 

NSLog(version); 

आउटपुट:

screenshot


और मैं देख रहा हूँ तुम बस संस्करण करना चाहते हैं। यह इस तरह से किया जा सकता है:

NSString *version = [[NSProcessInfo processInfo] operatingSystemVersionString]; 

NSRange range = NSMakeRange(8, 4); 
NSString *justVersion = [version substringWithRange: range]; 

NSLog(@"%@", justVersion); 

परिणाम:

screenshot

और जांच के लिए:

if ([justVersion isEqualToString:@"10.7"]) { 
    code... 
} 
else { 
    ... 
} 
+8

प्रलेखन में: "यह स्ट्रिंग पार्सिंग के लिए _not_ उपयुक्त है।" –

+1

यह बहुत गलत है। –

+0

यह भी ध्यान रखें कि उस स्ट्रिंग का प्रारूप उपयोगकर्ता के लोकेल के आधार पर भिन्न होता है। –

2

आप uname -r आदेश से मौजूदा रिलीज प्राप्त कर सकते हैं (जो वास्तव में है कर्नेल रिलीज, हालांकि मैक ओएस एक्स संस्करणों पर मैप करना आसान है), sw_vers कमांड से जो आपको रिलीज नाम, संस्करण और पहचानकर्ता बनाएं, या Gestalt() फ़ंक्शन से (मैक ओएस एक्स के मौजूदा संस्करणों पर, वैसे भी)। सबसे सुरक्षित तरीका शायद sw_vers के आउटपुट को पढ़ने के लिए है जो स्थिर प्रारूप में है जो पार्स करना आसान है।

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

11

एक त्वरित तरीका यह करने के लिए है:

if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_7) { 

    // Do stuff for Lion or later 
} 

अधिक here

आप NSApplication.h में उपलब्ध सभी स्थिरांक देख सकते हैं, जिन्हें आप एक्सकोड में ओपन क्विकली ... (सीएमडी-शिफ्ट ओ) का उपयोग करके प्राप्त कर सकते हैं।

हेडर फाइलें कुछ आश्चर्यजनक रूप से दिलचस्प पढ़ने सामग्री प्रदान करती हैं, यदि आप इतनी इच्छुक हैं।

+0

मुझे लगता है कि शॉर्टकट डिफ़ॉल्ट रूप से सीएमडी-शिफ्ट-डी है – cdelacroix

+2

इस समस्या में यह है कि इसमें मैक ओएस एक्स के प्रत्येक संशोधन को शामिल नहीं किया गया है, और भविष्य के सबूत के लिए कोई रास्ता नहीं है (उदाहरण के लिए यदि आप कोशिश कर रहे हैं नैदानिक ​​उद्देश्यों के लिए ओएस संस्करण की रिपोर्ट करें।) –

4

जैसा कि अन्य ने ऊपर कहा है (और मैं स्टीवन फिशर का जवाब लेता हूं), आप आमतौर पर संस्करण संख्या प्राप्त नहीं करना चाहते हैं।

और यदि आपको केवल मौजूदा एसडीके के संस्करण के लिए एक प्रमुख ओएस एक्स संस्करण के खिलाफ तुलना करने की आवश्यकता है, तो आप इसका उपयोग कर रहे हैं, NSAppKitVersionNumber (जैसा कि मोनोलो के उत्तर में है) इसे करने का सही तरीका है।

यदि आपको वास्तव में किसी कारण के लिए संस्करण संख्या प्राप्त करने की आवश्यकता है (उदाहरण के लिए, अपने उपयोगकर्ताओं के बारे में विश्लेषण रिकॉर्ड करने के लिए, तो आप तय कर सकते हैं कि 10.6.0-10.6.5 का समर्थन करना बंद करना कब है), यहां यह कैसे करें:

#import <CoreServices/CoreServices.h> 
SInt32 majorVersion, minorVersion, bugFixVersion; 
Gestalt(gestaltSystemVersionMajor, &majorVersion); 
Gestalt(gestaltSystemVersionMinor, &minorVersion); 
Gestalt(gestaltSystemVersionBugFix, &bugFixVersion); 

10.7.3 के लिए, यह majorVersion = 10, minorVersion = 7, bugFixVersion देता = 3.

10.7 प्रलेखन पैरा कि सीधे रास्ते OS संस्करण प्राप्त करने के लिए के रूप में गेस्टाल्ट सुझाव हटा दिया है, लेकिन यह है अभी भी बहिष्कृत या विरासत नहीं है, और कोई अन्य सुझाव नहीं है। असल में, इस जानकारी को प्राप्त करने के हर दूसरे तरीके (पार्सिंग - [एनएसपीक्रैसइन्फो ऑपरेटिंग सिस्टम सिस्टम वर्जनिंग], "kern.osrelease" पर sysctlbyname को कॉल करना और डार्विन कर्नेल संस्करण को ओएस एक्स संस्करण में कनवर्ट करना आदि) स्पष्ट रूप से कहीं से संकेतित है।तो, अगर आप वास्तव में करना चाहते हैं, तो ऐसा करने का यह तरीका है।

बस ध्यान रखें कि, सिस्टम 6.0.4 के रिलीज नोट्स के रूप में 1 9 8 9 में कहा गया था, यह नया एपीआई स्थायी नहीं हो सकता है और ओएस के भविष्य के संस्करण में हटाया जा सकता है।

+0

सुनिश्चित करें कि आप यह कर रहे हैं कि आप तुलना सही ढंग से लिखते हैं। मेरी कंपनी में कोई (मुझे नहीं (विंक)) एक बार एक दिनचर्या लिखा जिसने 10.3.0 से 10.3.1 की तुलना में 10.4.0 का पता लगाया, क्योंकि 0 1 से कम था। :) –

+0

@StevenFisher: मैंने कभी ऐसा नहीं किया है; जब मैंने अधिक मतलब किया तो मैंने अभी एक बराबर बराबर किया। :) लेकिन अधिक आम समस्या पूरी चीज को एक स्ट्रिंग में परिवर्तित कर रही है और फिर तारों की तुलना कर रही है, जो 10.4.10 तक पूरी तरह से काम करती है (क्योंकि "10.4.10" "10.4.9" से कम है)। आप इससे बचने के लिए NSNumericSearch/kCFCompare संख्यात्मक रूप से उपयोग कर सकते हैं-लेकिन इससे भी आसान, स्ट्रिंग करने से पहले संख्याओं की तुलना करें। – abarnert

0

यहां कोड है कि मैं इसे कैसे करता हूं। मैं इसे इस तरह से प्यार करता हूं, मुख्य रूप से क्योंकि मुझे ए नहीं है) एनएसटीस्क या बी पर निर्भर) किसी भी फ़ाइल I/O पर निर्भर है कि कई प्रक्रियाओं तक पहुंच है।

static NSString* const kVarSysInfoVersionFormat = @"%@.%@.%@ (%@)"; 
static NSString* const kVarSysInfoKeyOSVersion = @"kern.osrelease"; 
static NSString* const kVarSysInfoKeyOSBuild = @"kern.osversion"; 

- (NSString *) _strControlEntry:(NSString *)ctlKey { 

    size_t size = 0; 
    if (sysctlbyname([ctlKey UTF8String], NULL, &size, NULL, 0) == -1) return nil; 

    char *machine = calloc(1, size); 

    sysctlbyname([ctlKey UTF8String], machine, &size, NULL, 0); 
    NSString *ctlValue = [NSString stringWithCString:machine encoding:[NSString defaultCStringEncoding]]; 

    free(machine); return ctlValue; 
} 

- (NSString *) getOSVersionInfo { 

    NSString *darwinVer = [self _strControlEntry:kVarSysInfoKeyOSVersion]; 
    NSString *buildNo = [self _strControlEntry:kVarSysInfoKeyOSBuild]; 
    if (!darwinVer || !buildNo) return nil; 

    NSString *majorVer = @"10", *minorVer = @"x", *bugFix = @"x"; 
    NSArray *darwinChunks = [darwinVer componentsSeparatedByCharactersInSet:[NSCharacterSet punctuationCharacterSet]]; 

    if ([darwinChunks count] > 0) { 

     NSInteger firstChunk = [(NSString *)[darwinChunks objectAtIndex:0] integerValue]; 
     minorVer = [NSString stringWithFormat:@"%ld", (firstChunk - 4)]; 
     bugFix = [darwinChunks objectAtIndex:1]; 

    } return [NSString stringWithFormat:kVarSysInfoVersionFormat, majorVer, minorVer, bugFix, buildNo]; 
} 

आनंद लें!

2

स्टीवन फिशर ने कहा, आपको सिस्टम संस्करण की जांच नहीं करनी चाहिए, बल्कि उस वर्ग या विधि की उपलब्धता के लिए आप उपयोग करना चाहते हैं।

जांच कर लें कि एक विशिष्ट वर्ग उपलब्ध उपयोग

if ([NSHologram class]) { 
    // Create an instance of the class and use it. 
} else { 
    // The Hologram class is not available. 
} 

अगर एक विशिष्ट विधि विधि की जाँच के लिए उपलब्ध उपयोग

NSString* hologramText = @"Hologram"; 
if ([hologramText respondsToSelector:@selector(convertHologram)]) { 
    [hologramText convertHologram]; 
} 

फिर भी है की जाँच करने के लिए, विधि सिस्टम पर उपलब्ध होना चाहिए जहां आप अपना ऐप बनाते हैं, अन्यथा आपको एक संकलन त्रुटि मिल जाएगी।