उद्देश्य-सी कक्षा में एक स्विफ्ट प्रोटोकॉल का आयात करना


116

मैं नाम के AnalyticProtocolएक उद्देश्य-सी वर्ग में स्विफ्ट प्रोटोकॉल को आयात करने की कोशिश करता हूं AnalyticFactory

protocol AnalyticProtocol
{

}

मैं एक मौजूदा ऑब्जेक्टिव-सी परियोजना से शुरू कर रहा हूं (मैंने xCode के साथ एक नई स्विफ्ट परियोजना नहीं बनाई है और मैंने नहीं पाया कि xCode 6 में एक स्विफ्ट परियोजना होने के लिए मैं अपने उद्देश्य-सी परियोजना को कैसे कॉन्फ़िगर करता हूं )।

मेरी स्विफ्ट फ़ाइल में मैंने .hनाम वाली फ़ाइल शामिल की, MyProjectName-Swift.hलेकिन कंपाइलर ने मुझे यह बताकर एक त्रुटि लौटा दी कि यह मौजूद नहीं है । इसलिए, मैंने एक .hफाइल बनाई जिसका नाम MyProjectName-Swift.hवास्तव में खाली है (मुझे नहीं पता कि मुझे अंदर क्या डालना चाहिए)।

में एप्पल प्रलेखन उन्होंने कहा कि मैं अपने में शामिल करने के लिए है .hफ़ाइल का नाम MyProjectName-Swift.hमेरे में .mफ़ाइल। लेकिन मुझे इसे अपनी .mफ़ाइल में नहीं बल्कि अपने में शामिल करने की आवश्यकता है.h । क्या यह समस्याग्रस्त हो सकता है?

जब मैं संकलित करने की कोशिश करता हूं तो मुझे यह त्रुटि मिली है : 0: त्रुटि: xxxAnalyticFactory.h: 39: 'AnalyticsProtocol' के लिए प्रोटोकॉल घोषणा नहीं मिल सकती है

और गुप्त कोड:

@interface AnalyticFactory : NSObject
{
    Class<AnalyticProtocol> _analyticProtocolClass; // The type of the analytic class currently used.
}

मुझे लगता है कि मुझे अच्छी तरह से समझ नहीं आ रहा है कि मैं एक ऑब्जेक्टिव-सी क्लास में स्विफ्ट प्रोटोकॉल कैसे आयात कर सकता हूं।

किसी को भी मैं क्या कर रहा हूँ में एक त्रुटि देखता है?


डब्ल्यूडब्ल्यूडीसी 2014 से वस्तुनिष्ठ-सी वीडियो के साथ एकीकृत स्विफ्ट की जाँच करें । वीडियो में लगभग 30:40 पर, वे वर्णन करते हैं कि ऑब्जेक्ट-सी कक्षाओं में स्विफ्ट प्रोटोकॉल का उपयोग कैसे करें।
जेमी फॉरेस्ट

जवाबों:


224

आपको @objcअपने स्विफ्ट प्रोटोकॉल में विशेषता जोड़ने की आवश्यकता है जैसे:

@objc protocol AnalyticProtocol {

}

25
आपके उत्तर के लिए धन्यवाद, लेकिन समस्या अभी भी बनी हुई है।
जीन लेब्रिनेट

क्या आप शायद एक नमूना परियोजना पोस्ट कर सकते हैं जो इस मुद्दे को पुन: पेश करता है?
जेमी फॉरेस्ट

@Objc को जोड़ने से मुझे स्विफ्ट क्लासेस को Obj-C
serg

19
@objc हमेशा काम नहीं करता है। प्रोटोकॉल के अनुरूप होने पर कभी-कभी फ़ाइल @interfaceमें प्रोटोकॉल जोड़ने पर यह काम नहीं करता है .h। हालाँकि, आप फ़ाइल @interfaceमें प्रोटोकॉल को निजी में जोड़ सकते हैं .mऔर यह चीजों को ठीक कर देता है (कम से कम मेरे पास इस अवसर पर)। तो ऊपर अपना @implementationहै @interface MyController() <AnalyticProtocol>
एडम

1
कभी-कभी आप संपादन करते समय Xcode 8 की शिकायत करेंगे, लेकिन जब आप वास्तव में इसका निर्माण करेंगे, तो टिप्पणियों के साथ इस उत्तर का अनुसरण करते हुए, त्रुटि दूर हो जाएगी।
रोजर पिंगलटन

77

ObjC हेडर फ़ाइलों में Xcode जनरेट स्विफ्ट हेडर आयात करना संभव नहीं है।

इसलिए, चूंकि आप एक objC हेडर फ़ाइल में स्विफ्ट कोड का उपयोग करना चाहते हैं, इसलिए आपको objC हेडर फ़ाइल में जिन वर्गों और प्रोटोकॉल का उपयोग करना है, उन्हें "आगे घोषित" करना होगा।

@protocol AnalyticProtocol;

अब आप अपने objC वर्ग घोषणा में प्रोटोकॉल का उपयोग कर सकते हैं:

@interface AnalyticFactory : NSObject
{
    Class<AnalyticProtocol> _analyticProtocolClass; // The type of the analytic class currently used.
}

आपकी कार्यान्वयन फ़ाइल (objC .m फ़ाइल) में, आप Xcode उत्पन्न स्विफ्ट हेडर ("ProductModuleName-Swift.h") फ़ाइल और सही कार्यान्वयन आयात कर सकते हैं AnalyticProtocol अब कंपाइलर को पता चल जाएगा।

यह एप्पल डॉक्स में "ऑब्जेक्टिव-सी से स्विफ्ट का उपयोग करना" अनुभाग में भी वर्णित है

ध्यान दें कि जब आप आगे घोषित प्रोटोकॉल का उपयोग करते हैं, तो XCode objC हेडर फ़ाइल में एक चेतावनी देगा ("'एनालिटिकप्रोटोकॉल' के लिए प्रोटोकॉल परिभाषा नहीं मिल सकती है), लेकिन इसे अनदेखा किया जा सकता है - कार्यान्वयन संकलन समय पर मिल जाएगा।


19
जब यह संकलित करता है और ठीक काम करता है तो एक्सकोड गुम प्रोटोकॉल के लिए चेतावनी क्यों दिखाता है? चेतावनी को हटाने का कोई तरीका?
ओरेन

हालांकि इस वर्ग पर प्रोटोकॉल विधियों को कॉल करना अभी भी संभव नहीं है। यह त्रुटि दे देंगेNo visible @interface for <ClassName> declares the selector <protocolMethodName>
एल्सा

यह निम्नलिखित चेतावनी उत्पन्न करता है: "xxxx के लिए प्रोटोकॉल परिभाषा नहीं पा सकता"
जेहेलिया

51

किसी को भी, जिसे बस एक प्रोटोकॉल अपनाने की आवश्यकता है - आप इसे दो चरणों में कर सकते हैं, बिना किसी चेतावनी या त्रुटि के।

  1. अपनी .swiftफ़ाइल में, @objcप्रोटोकॉल नाम से पहले जोड़ें :

    @objc protocol AnalyticProtocol {
    
    }
  2. अपनी .mफाइल में, जेनरेट स्विफ्ट हेडर आयात करें और प्रोटोकॉल को निजी श्रेणी में अपनाएं। (शीर्षक फ़ाइल को स्वचालित रूप से नाम दिया गया है):

    #import "ProductModuleName-Swift.h"
    
    @interface AnalyticFactory () <AnalyticProtocol>
    
    @end

यह Apple का अनुशंसित दृष्टिकोण है। आप उद्देश्य और सी और स्विफ्ट के मिश्रण और मिलान के बारे में अधिक जान सकते हैं: https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixMMatch.html


1
मुझे अभी भी चेतावनी मिली है, आगे की घोषणा के साथ या बिना। मैं एक एक्सटेंशन में प्रोटोकॉल का उपयोग कर रहा हूं।
Cristi Băluță

आयात नहीं कर सकता #import "AnalyticProtocol-Swift.h"। ऐसा लगता है कि जो कुछ भी आपके द्वारा कहा गया है, वह कोई भी ऑटो-चॉकलेट-स्विफ्ट नहीं है।
ह्लुंग

2
इसने मेरे लिए काम किया; इस पृष्ठ पर किसी अन्य सुझाव या उत्तर ने काम नहीं किया। मैं स्विफ्ट 4 पर हूं।
पॉल्सो

1
यह चेतावनी को हटाने का एकमात्र तरीका था (भले ही यह काम करता है जब प्रोटोकॉल हेडर फाइल में होते हैं)
डेविड पी


3

यदि आपका एक ढांचा बना रहे हैं, तो आवश्यक आयात

#import "ProductModuleName-Swift.h"

में परिवर्तन:

#import <ProductModuleName/ProductModuleName-Swift.h>

इस मामले में आपको स्विफ्ट प्रोटोकॉल को भी सार्वजनिक करना होगा :

@objc public protocol AnalyticProtocol {
  func something();
}

3

हम कोड में कुछ परिवर्तनों के साथ Objective C में स्विफ्ट प्रोटोकॉल का उपयोग कर सकते हैं। इसके अलावा, @objc घोषित प्रोटोकॉल आपको डिफ़ॉल्ट कार्यान्वयन के बिना वैकल्पिक और आवश्यक तरीके प्रदान करते हैं। यह पेशेवरों और विपक्षों के साथ आता है।

हम वास्तव में एक और वर्णनात्मक के लिए प्रोटोकॉल का नाम फिर से नाम कर सकते हैं जब उद्देश्य सी में उपयोग किया जाता है। मैं "@objc (alias_name)" का उपयोग करता हूं।

यहाँ कोड है, आइए ओब्जेक्ट कोड में उपयोग करने के लिए @objc विशेषता और उपनाम नाम के साथ एक स्विफ्ट प्रोटोकॉल है।

@objc(ObjTableViewReloadable) protocol TableViewReloadable: class {
   func reloadRow(at index: IndexPath)
   func reloadSection(at index: Int)
   func reloadTable()
}

अब फ़ॉरेस्ट को हमारे प्रोटोकॉल को .h फ़ाइल में घोषित करने देता है

@protocol ObjTableViewReloadable;

अब आप .m फ़ाइल में इस प्रोटोकॉल के अनुरूप हो सकते हैं और आवश्यक विधियों को लागू कर सकते हैं।

#import "MyApp-Swift.h"
@interface MyObjcViewController () <ObjTableViewReloadable>

इसे पोस्ट करने के लिए आपका धन्यवाद। मैं विरासत कोड को देख रहा हूं जो गंदगी से भी पुराना है और अगर यह दृष्टिकोण काम करता है, तो यह मुझे एक टन दर्द से बचाएगा। :)
एड्रियन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.