प्रीप्रोसेसर मैक्रोज़ की अनुपस्थिति में, एक्सकोड परियोजना में परियोजना स्तर पर व्यावहारिक योजना विशिष्ट झंडे को परिभाषित करने का एक तरीका है


174

स्विफ्ट से पहले मैं अल्फा, बीटा, और वितरण बिल्ड के लिए योजनाओं का एक सेट परिभाषित करूंगा। इन योजनाओं में से प्रत्येक में मैक्रो का एक सेट होगा जो परियोजना स्तर पर कुछ निश्चित व्यवहार को निर्धारित करने के लिए परिभाषित किया गया था। सबसे सरल उदाहरण DEBUG = 1 मैक्रो है जो डिफ़ॉल्ट रूप से रन निर्माण के लिए डिफ़ॉल्ट योजना में सभी Xcode परियोजनाओं के लिए परिभाषित किया गया है। कोई भी #ifdef DEBUG को क्वेरी कर सकता है ... और गैर-आवश्यक कोड संकलित करते हुए, तदनुसार कोड में निर्णय ले सकता है।

ऐसा लगता है कि इस प्रकार के विन्यास संबंधी गेटिंग स्विफ्ट का उपयोग करना उतना आसान नहीं है, क्योंकि मैक्रोज़ समर्थित नहीं हैं। क्या कोई तुलनीय दृष्टिकोण सुझा सकता है, मुझे परवाह नहीं है कि क्या कोड संकलित किया गया है, प्रति से। हालांकि, मैं बिल्ड स्कीम के आधार पर गेट फीचर्स लेना चाहूंगा।

जवाबों:


468

स्विफ्ट में आप अभी भी Apple डॉक्स के अनुसार "# अगर / # और / # एंडिफ" प्रीप्रोसेसर मैक्रोज़ (हालांकि अधिक विवश) का उपयोग कर सकते हैं । यहाँ एक उदाहरण है:

#if DEBUG
    let a = 2
#else
    let a = 3
#endif

हालांकि, आपको "DEBUG" प्रतीक को कहीं और सेट करना होगा, हालांकि। इसे "स्विफ्ट कंपाइलर - कस्टम फ्लैग" अनुभाग, "अन्य स्विफ्ट फ्लैग" लाइन में सेट करें। आप -D DEBUGप्रविष्टि के साथ DEBUG प्रतीक जोड़ें ।

(बिल्ड सेटिंग्स -> स्विफ्ट कंपाइलर - कस्टम फ्लैग) यहां छवि विवरण दर्ज करें

हमेशा की तरह, आप डिबग में या रिलीज़ होने पर एक अलग मान सेट कर सकते हैं।

मैंने इसे वास्तविक कोड में परीक्षण किया; यह एक खेल के मैदान में पहचाना नहीं लगता है।


5
ध्यान दें कि आप अधिक परीक्षण जोड़ने के लिए #elseif लाइनों का उपयोग कर सकते हैं। दिलचस्प रूप से पर्याप्त है, आप परिभाषा तक पहुंच सकते हैं, लेकिन इसमें से कुछ भी नहीं निकाल सकते हैं; वह है, परिभाषित -DDEBUG = 5 (या = "FOO"), और फिर इसे "println (DEBUG है) (DEBUG) के साथ मुद्रित करने का प्रयास करें। यह पंक्ति कोई त्रुटि नहीं उत्पन्न करती है, लेकिन कुछ भी नहीं करती है।
डेविड एच।

10
नोट: "निर्मित सेटिंग्स -> स्विफ्ट कंपाइलर -> कस्टम फ़्लैग" "बेसिक" बिल्ड सेटिंग्स में दिखाई नहीं देते हैं। दिखाई देने के लिए "सभी" बिल्ड सेटिंग्स दिखाना होगा।
लेविबोस्टियन

7
@EugeneDubinin शायद इसलिए क्योंकि आपको यह सुनिश्चित करना चाहिए कि $(inherited)लक्ष्य सेटिंग्स में प्रोजेक्ट सेटिंग्स को इनहेरिट करने के लिए उपयोग किया जाता है।
दानस्किल

2
@DanSkeel अच्छी पकड़, $(inherited)मेरी टिप्पणी को अप्रासंगिक बनाता है, धन्यवाद!
येविन दुबिनिन

10
Xcode 8 में अब "स्विफ्ट कंपाइलर - कस्टम फ्लैग" सेक्शन में एक "एक्टिव कंप्लायंस कंडीशंस" सेटिंग भी है। आप बिना डी
मार्क के

32

हम स्विफ्ट कंपाइलर झंडे सेट न करने के मुद्दे के साथ भागे क्योंकि हम उन्हें सेट नहीं करना चाहते थे और उन्हें अलग-अलग लक्ष्यों आदि के लिए अद्यतित रखना चाहते थे। इसके अलावा, हमारे मिश्रित कोडबेस में, हम याद रखना नहीं चाहते थे। प्रत्येक भाषा के लिए हर समय उचित रूप से हमारे झंडे लगाने के लिए।

हमारे लिए, हमने ObjC में एक फ़ाइल घोषित की

PreProcessorMacros.h

extern BOOL const DEBUG_BUILD;

उनमे

PreProcessorMacros.m

#ifdef DEBUG
    BOOL const DEBUG_BUILD = YES;
#else
    BOOL const DEBUG_BUILD = NO;
#endif

फिर, अपने ऑब्जेक्टिव-सी ब्रिजिंग हैडर में

#import "PreProcessorMacros.h"

अब, अपने स्विफ्ट कोडबेस में इसका उपयोग करें

if DEBUG_BUILD {
    println("debug")
} else {
    println("release")
}

यह निश्चित रूप से एक समाधान है, लेकिन इसने हमारी समस्या को हल कर दिया है इसलिए मैंने इसे यहाँ इस उम्मीद में पोस्ट किया है कि यह मदद करेगा। यह सुझाव देने के लिए नहीं है कि मौजूदा उत्तर अमान्य हैं।


11
मैक्रो का पूरा बिंदु बिल्ड कॉन्फ़िगरेशन के आधार पर कोड को बदलना है। यदि आप रनटाइम में वापस ला रहे हैं, तो आपको उसके लिए मैक्रो की आवश्यकता नहीं है।
बेरिक

18
@Berik - मैंने इस उम्मीद में एक वैध समाधान पोस्ट किया कि यह दूसरों को भी इस समस्या के एक पहलू को सुलझाने में मदद कर सकता है, खासकर बहु-भाषा परियोजनाओं में। यदि आपकी समस्या को विशिष्ट कोड संकलित करने की आवश्यकता नहीं है जो ठीक है। इसके अलावा एक टिप्पणी ठीक है, खासकर जब यह कुछ शिक्षित करता है कि यह उनके लिए समाधान क्यों नहीं हो सकता है। इस दृष्टिकोण की सीमाओं के बारे में जवाब में एक नोट बनाने के लिए कह रहा है। डाउनवोटिंग अनावश्यक है और वैकल्पिक समाधानों को हतोत्साहित करता है जो अन्य समान समस्याओं को हल करने में सहायक हो सकते हैं। इसके अलावा, op का कहना है कि "मुझे परवाह नहीं है कि क्या कोड संकलित है"।
लोगन

5

लोगान विधि के लिए अधिक सूजी घोल। सेट -D DEBUGमें Other Swift Flagsसे Swift Compiler - Custom Flagsअपने लक्ष्य के निर्माण सेटिंग्स में अनुभाग।

फिर वैश्विक दायरे में निम्नलिखित विधि घोषित करें:

#if DEBUG
let isDebugMode = true
#else
let isDebugMode = false
#endif

अब इसका उपयोग करें

if isDebugMode {
    // Do debug stuff
}

1

मेरे लिए, " सक्रिय संकलन स्थिति " के डिबग आइटम को "DEBUG" पर सेट करें ।

तब #IF DEBUG में डिबग कार्य में डिबग्यू प्रमुख कार्य का उपयोग करना और रिलीज मोड में #ELSE:

  1. अपना लक्ष्य चुनें,
  2. "सक्रिय संकलन स्थिति" के लिए सेटिंग सेटिंग टैब खोज में,
  3. अपने "डीबग" आइटम का मूल्य "YourKeyWord" पर सेट करें,
  4. बस अनुसरण के रूप में उपयोग करें:

    #if DEBUG
        print("You'r running in DEBUG mode!")
    #else
        print("You'r running in RELEASE mode!")
    #endif
    

0

मैं एक मिश्रित भाषा कोड बेस में काम कर रहा हूं, जहां obj-c कोड कंसोल में डिबग संदेश भेजने के लिए मैक्रो का उपयोग करता है (और यह मैक्रो हमारे डीबग प्रीप्रोसेसर ध्वज पर निर्भर करता है)। मैं स्विफ्ट कोड में उसी मैक्रो को कॉल करने में सक्षम होना चाहता था ...

  1. मैंने अपने obj-c वर्गों में से एक पर एक वर्ग विधि बनाई जो उस मैक्रो के चारों ओर एक आवरण है।
  2. मैंने उस ब्रिज-हेडर फ़ाइल में obj-c हेडर जोड़ा है।
  3. अब मेरा स्विफ्ट कोड ओबज-सी मैक्रो के लिए "प्रॉक्सी" के रूप में उस क्लास विधि को कॉल करता है।

यह स्वाभाविक रूप से कष्टप्रद है कि मैं केवल मैक्रो को स्विफ्ट कोड में सीधे कॉल नहीं कर सकता, लेकिन कम से कम अब मेरे पास प्रोजेक्ट में केवल एक जगह है जो अपने डिबग फ्लैग को चालू / बंद करने के बारे में चिंता करने के लिए है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.