क्या ओज-सी में स्विफ्ट के एनम का उपयोग करना संभव है?


145

मैं अपने कुछ ओज-सी वर्ग को स्विफ्ट में बदलने की कोशिश कर रहा हूं। और कुछ अन्य ओब्ज-सी कक्षाएं अभी भी उस परिवर्तित वर्ग में एनम का उपयोग कर रही हैं। मैंने प्री-रिलीज़ डॉक्स में खोज की और वह नहीं मिली या शायद मैं इसे मिस कर गया। क्या ओब्ज-सी क्लास में स्विफ्ट एनम का उपयोग करने का एक तरीका है? या इस मुद्दे के डॉक्टर के लिए एक कड़ी?

इस तरह से मैंने अपने पुराने ओब्ज-सी कोड और नए स्विफ्ट कोड में अपना एनम घोषित किया।

मेरा पुराना ओब्ज-सी कोड:

typedef NS_ENUM(NSInteger, SomeEnum)
{
    SomeEnumA,
    SomeEnumB,
    SomeEnumC
};

@interface SomeClass : NSObject

...

@end

मेरा नया स्विफ्ट कोड:

enum SomeEnum: NSInteger
{
    case A
    case B
    case C
};

class SomeClass: NSObject
{
    ...
}

अपडेट: उत्तरों से। यह स्विफ्ट पुराने संस्करण में 1.2 से अधिक नहीं किया जा सकता है। लेकिन इस आधिकारिक स्विफ्ट ब्लॉग के अनुसार । XCode 6.3 के साथ जारी स्विफ्ट 1.2 में, आप @objcसामने जोड़कर ऑब्जेक्टिव-सी में स्विफ्ट एनम का उपयोग कर सकते हैंenum


आपके मौजूदा कोड को बदलने की वास्तव में कोई आवश्यकता नहीं है। स्विफ्ट और ऑब्जेक्टिव-सी के बीच बातचीत के लिए, WWDC वीडियो देखें।
gnasher729

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

जवाबों:


226

स्विफ्ट संस्करण 1.2 (Xcode 6.3) के अनुसार आप कर सकते हैं। बस एनम घोषणा के साथ उपसर्ग करें@objc

@objc enum Bear: Int {
    case Black, Grizzly, Polar
}

बेशर्मी से स्विफ्ट ब्लॉग से लिया गया

नोट: यह स्ट्रिंग एनम या एनम से जुड़े मूल्यों के लिए काम नहीं करेगा। आपके एनम को इंट-बाउंड होना होगा


ऑब्जेक्टिव-सी में ऐसा दिखेगा

Bear type = BearBlack;
switch (type) {
    case BearBlack:
    case BearGrizzly:
    case BearPolar:
       [self runLikeHell];
}

8
यह इंगित करने के लिए बहुत बहुत धन्यवाद ... ध्यान दें कि उद्देश्य-सी में हालांकि एनम मूल्यों को कॉल किया जाएगा BearBlack, BearGrizzlyऔर BearPolar!
nburk

1
यह समझ में नहीं आता है? विशेष रूप से जब आप यह देखते हैं कि यह कैसे obj-c से स्विफ्ट में अनूदित है .. @nburk
डैनियल गैलास्को

1
हां, यह काम करता है। : "@Objc सार्वजनिक enum भालू: इंट" हालांकि, मेरे मामले में कम से कम एक "सार्वजनिक" विशेषता, गणन करने के लिए जोड़ा जा करने के लिए यह परियोजना के ऑब्जेक्टिव-सी की ओर से सुलभ होने के लिए इस तरह था
Pirkka Esko

बहुत बुरा मुझे कोई सबूत नहीं दिखता है कि स्विफ्ट एनम से जुड़े मूल्य संभव हैं। इच्छाधारी सोच
finneycanhelp

2
@AJit आप ऐसा क्यों करना चाहेंगे? बस अपने खुद के हेडर में
एनम

31

चयनित उत्तर पर विस्तार करने के लिए ...

स्विफ्ट और ऑब्जेक्टिव-सी के बीच स्विफ्ट स्टाइल एनम को साझा करना संभव है NS_ENUM()

उन्हें बस एक उद्देश्य-सी के संदर्भ में परिभाषित करने की आवश्यकता है NS_ENUM()और उन्हें स्विफ्ट डॉट नोटेशन का उपयोग करके उपलब्ध कराया गया है।

से कोको के साथ का उपयोग करते हुए स्विफ्ट और ऑब्जेक्टिव-सी

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

उद्देश्य सी

typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
   UITableViewCellStyleDefault,
   UITableViewCellStyleValue1,
   UITableViewCellStyleValue2,
   UITableViewCellStyleSubtitle
};

तीव्र

let cellStyle: UITableViewCellStyle = .Default

मैं UITableViewCellStyle में मिलता हूं "फ़ंक्शन की परिभाषा यहां अनुमति नहीं है", मैं क्या गलत कर रहा हूं? बेशक, मेरे पास अलग-अलग नाम नहीं हैं UITableViewCellStyle।
बजे क्रिस्टी बालूओ

1
जैसा कि नीचे श्री गैलास्को के जवाब में कहा गया है, स्विफ्ट 1.2, एनम को स्विफ्ट में परिभाषित करने और ओब्ज-सी में उपलब्ध होने की अनुमति देता है। परिभाषा की यह शैली, अर्थात् NS_ENUM, अभी भी Obj-c में काम करती है, लेकिन Swift संस्करण 1.2 के रूप में आपके पास या तो विकल्प का उपयोग किया जा सकता है।
सिरनॉड

मैंने पाया कि Swift में ObjC enums के साथ एक समस्या है: वे उपलब्ध नहीं हैं। एक खंड में if let a = MyEnum(rawValue: 12345)जहां 12345 उस एनम का हिस्सा नहीं है, परिणाम एक वैकल्पिक नहीं है, लेकिन कुछ अमान्य एनम है।
जैव

30

से कोको और ऑब्जेक्टिव-सी के साथ का उपयोग करते हुए स्विफ्ट गाइड:

उद्देश्य-सी में सुलभ और प्रयोग करने योग्य होने के लिए एक स्विफ्ट क्लास या प्रोटोकॉल को @objc विशेषता के साथ चिह्नित किया जाना चाहिए। [...]

जब तक यह ऑब्जेक्टिव-सी के साथ संगत है, तब तक आपको किसी भी वर्ग या प्रोटोकॉल में एक्सेस करना होगा जो @objc विशेषता के साथ चिह्नित है। यह स्विफ्ट-केवल सुविधाओं को शामिल करता है जैसे कि यहां सूचीबद्ध हैं:

जेनेटिक्स टुपल्स / गणना स्विफ्ट / संरचना में परिभाषित स्विफ्ट / टॉप-लेवल फ़ंक्शंस में परिभाषित स्विफ्ट / ग्लोबल वैरिएबल में परिभाषित स्विफ्ट / टाइपराइलैस को स्विफ्ट / स्विफ्ट-स्टाइल वेरिएडिक्स में परिभाषित / नीडेड प्रकार / क्युरिड फ़ंक्शंस

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


2
क्या आसपास कोई काम है? मेरा मतलब है अगर मैं एक स्विफ्ट क्लास बनाता हूं और मुझे पूरी तरह से एक एनम की जरूरत है। मैं उस एनम को उद्देश्य-सी में भी प्रयोग करने योग्य कैसे बना सकता हूँ?
राउल लोपेज 16

4
@RaLLopezVillalpando यदि आपको पता है कि आप ऑब्जेक्टिव-सी के साथ इंटरऑपरेटिंग करने जा रहे हैं, तो आपको ऑब्जेक्टिव-सी में एन्यूमरेशन की घोषणा करनी चाहिए और दोनों भाषाओं को शेयर करने देना चाहिए।
ग्रेगरी हिगले

3
"हाँ, इसलिए हमने स्विफ्ट में संक्रमण करने में आपकी मदद करने के लिए यह पुल बनाया है, लेकिन बेकार है अगर आप किसी भी शांत चीज़ का उपयोग करना चाहते हैं, जैसे Enums, Structs, Generics ... तो वहाँ है कि ..."
केविन आर

22
यह उत्तर कोई वैध नहीं है !! चूँकि Xcode 6.3 / Swift 1.2, Swift enums का उपयोग उद्देश्य-ग के भीतर भी किया जा सकता है, @objcजैसा कि @DanielGalasko ने नीचे दिए गए अपने उत्तर में बताया है !!!
nburk

9
उपरोक्त टिप्पणी को स्पष्ट करने के लिए, Swift 2.1 के रूप में दस्तावेज़ीकरण के वर्तमान पाठ को उद्धृत करते हुए , "इन्ट्यूशन को परिभाषित किए बिना स्विफ्ट में Int रॉ मान प्रकार "। इसलिए, यदि स्विफ्ट में आपका एनम एक इंट कच्चे मान के साथ घोषित किया गया है क्योंकि @obj enum MyEnum: Intयह ऑब्जेक्ट-सी फाइलों पर ठीक काम करेगा जैसा कि पहले बताया गया है। यदि आपकी एनम को दूसरे कच्चे मूल्य प्रकार के साथ घोषित किया जाता है @obj enum MyOtherEnum: String, तो आप इसे ऑब्जेक्ट-सी फ़ाइलों पर उपयोग नहीं कर पाएंगे
jjramos

7

स्विफ्ट 4.1, एक्सकोड 9.4.1:

1) स्विफ्ट एनम को उपसर्ग के साथ टाइप @objcकिया जाना चाहिए Int:

// in .swift file:
@objc enum CalendarPermission: Int {
    case authorized
    case denied
    case restricted
    case undetermined
}

2) उद्देश्य-सी नाम enum name + case name, उदा CalendarPermissionAuthorized:

// in .m file:
// point to something that returns the enum type (`CalendarPermission` here)
CalendarPermission calPermission = ...;

// use the enum values with their adjusted names
switch (calPermission) {
    case CalendarPermissionAuthorized:
    {
        // code here
        break;
    }
    case CalendarPermissionDenied:
    case CalendarPermissionRestricted:
    {
        // code here
        break;
    }
    case CalendarPermissionUndetermined:
    {
        // code here
        break;
    }
}

और, ज़ाहिर है, उद्देश्य-सी फ़ाइल की आयात सूची में अंतिम आइटम के रूप में अपने स्विफ्ट ब्रिजिंग हेडर को आयात करना याद रखें:

#import "MyAppViewController.h"
#import "MyApp-Swift.h"

MyApp-Swift अंतिम क्यों होना चाहिए?
पॉल टी।

@PaulT। : शायद प्रसंस्करण के आदेश के साथ क्या करना है। इसे कहीं और लगाने की कोशिश करें, और आप देखेंगे कि यह काम नहीं करेगा।
दुबला

मैंने अपनी वर्तमान परियोजना में लगभग सभी फ़ाइलों में जाँच की, यह आयात खंड के अंत में है, लेकिन कई फाइलों में यह अंत और परियोजना के काम में नहीं है। यह काम करता है एक नए Xcode में हो सकता है? मैं इसे अभी नहीं देख सकता, क्योंकि मेरी वर्तमान परियोजना को संकलित करने में उम्र लगती है :), लेकिन मैं इसे बाद में जाँचने वाला हूँ
पॉल टी।

2

यदि आप ObjC कोड्स को अपने पास रखना पसंद करते हैं, तो आप अपने प्रोजेक्ट में एक सहायक हेडर फ़ाइल जोड़ सकते हैं:

Swift2Objc_Helper.h

शीर्ष लेख फ़ाइल में यह एनम प्रकार जोड़ें:

typedef NS_ENUM(NSInteger, SomeEnum4ObjC)
{
   SomeEnumA,
   SomeEnumB
};

परिवर्तन करने के लिए आपकी .m फ़ाइल में एक और स्थान हो सकता है: छिपी हेडर फ़ाइल को शामिल करने के लिए:

#import "[YourProjectName]-Swift.h"

अपने प्रोजेक्ट के नाम के साथ [YourProjectName] बदलें। यह हेडर फ़ाइल सभी स्विफ्ट परिभाषित @objc वर्गों को उजागर करती है, जो कि ओम्जेसी को बताती है।

आपको गणना प्रकार से निहित रूपांतरण के बारे में चेतावनी संदेश मिल सकता है ... यह ठीक है।

वैसे, आप इस हेडर हेल्पर फ़ाइल का उपयोग कुछ ओबीजीसी कोड जैसे #define स्थिरांक रखने के लिए कर सकते हैं।


0

यदि आप (मेरे जैसे) वास्तव में स्ट्रिंग एनम का उपयोग करना चाहते हैं, तो आप उद्देश्य-सी के लिए एक विशेष इंटरफ़ेस बना सकते हैं। उदाहरण के लिए:

enum Icon: String {
    case HelpIcon
    case StarIcon
    ...
}

// Make use of string enum when available:
public func addIcon(icon: Icon) {
    ...
}

// Fall back on strings when string enum not available (objective-c):
public func addIcon(iconName:String) {
    addIcon(Icon(rawValue: iconName))
}

बेशक, यह आपको ऑटो-पूर्ण की सुविधा नहीं देगा (जब तक कि आप उद्देश्य-सी वातावरण में अतिरिक्त स्थिरांक को परिभाषित नहीं करते हैं)।


0

यह थोड़ा और अधिक मदद कर सकता है

समस्या कथन : - मेरे पास स्विफ्ट क्लास में एनम है, जिसे मैं अन्य स्विफ्ट क्लासेस के रूप में एक्सेस कर रहा हूं, और अब मुझे इसे एक्सेस करने के लिए अपना एक उद्देश्य सी क्लास बनाना होगा।

वस्तुनिष्ठ-ग वर्ग से इसे एक्सेस करने से पहले: -

enum NTCType   {
    case RETRYNOW
    case RETRYAFTER
}
 var viewType: NTCType? 

उद्देश्य सी वर्ग से इसे एक्सेस करने के लिए परिवर्तन

@objc  enum NTCType :Int  {
    case RETRYNOW
    case RETRYAFTER
}

और मूल्य पर इसे पारित करने के लिए एक फ़ंक्शन जोड़ें

  @objc  func setNtc(view:NTCType)  {
        self.viewType = view; // assign value to the variable
    }

0

इस पर शोध करने के बाद, मुझे केवल आंशिक उत्तर ही मिलते रहे, इसलिए मैंने ऑब्जेक्टिव C के लिए स्विफ्ट ऐप का एक संपूर्ण उदाहरण बनाया, जिसमें स्विफ्ट कोड्स का उपयोग किया गया है जिसका उपयोग ऑब्जेक्टिव सी कोड और ऑब्जेक्टिव सी एनमों का उपयोग स्विफ्ट कोड द्वारा किया गया है। यह एक सरल Xcode प्रोजेक्ट है जिसे आप चला सकते हैं और प्रयोग कर सकते हैं। यह स्विफ्ट 5.0 के साथ Xcode 10.3 का उपयोग करके लिखा गया था

उदाहरण परियोजना


मैं नहीं देखता, जहां आपका प्रोजेक्ट ऑब्जेक्टिव सी में स्विफ्ट enum SwAnimal@obj
एनम

0

यदि आप किसी एनम का पालन करने की कोशिश कर रहे हैं जो इस प्रकार है:

enum EnumName: String {
    case one = "One"
    case two = "Two"
}

इस वर्कअराउंड ने मेरी मदद की।

अवलोकनीय वर्ग:

  • सृजन करना @objc dynamic var observable: String?
  • इस तरह से अपना enum उदाहरण बनाएं:

    private var _enumName: EnumName? {
        didSet {
            observable = _enumName!.rawValue
        }
    }

प्रेक्षक वर्ग:

  • सृजन करना private var _enumName: EnumName?
  • सृजन करना private let _instance = ObservableClass()
  • सृजन करना

    private var _enumObserver: NSKeyValueObservation = _instance.observe(\.observable, options: .new, changeHandler: { [weak self] (_, value) in
        guard let newValue = value.newValue else { return }
        self?._enumName = EnumName(rawValue: period)!
    })

थान का है। अब हर बार जब आप _enumNameअवलोकनीय श्रेणी में बदलते हैं , तो पर्यवेक्षक वर्ग पर एक उपयुक्त उदाहरण तुरंत अद्यतन किया जाएगा।

यह निश्चित रूप से एक ओवरसाइम्प्लिफ़ाइड कार्यान्वयन है, लेकिन आपको केवीओ-असंगत गुणों का निरीक्षण करने का तरीका देना चाहिए।

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