उद्देश्य-सी वर्ग से स्विफ्ट फ़ंक्शन को कॉल करें


84

मेरे पास एक पुरानी उद्देश्य-सी परियोजना है और मैं नए स्विफ्ट फ़ंक्शन और ऑब्जेक्ट को कॉल करना चाहता हूं, मैंने फ़ाइल " <ProjectName>-Bridging-Header.h" और " <ProjectName>-Swift.h" बनाई है

मेरे लिए स्विफ्ट से ऑब्जेक्टिव-सी तक फ़ंक्शन को कॉल करना आसान था, लेकिन मुझे रिवर्स के लिए समस्या है।

इसलिए मैंने एक साधारण वर्ग "System.Swift" बनाया है

import Foundation

@objc class System : NSObject {

    @objc func printSome() {
        println("Print line System");
    }
    
}

अब मैंने यहाँ प्रलेखन का पालन ​​करने की कोशिश की है और <...>-Swift.hफ़ाइल के अंदर मैंने इसे लिखा है

@class System;

@interface System : NSObject

-(void)printSome;

@end

और मैंने इसे अपने Objective-C Class के अंदर आयात किया है। मेरे उद्देश्य-सी कोड के मेरे उद्देश्य सी वर्ग (वर्तमान में UIViewController) के अंदर इस बिंदु पर मुझे "प्रिंटसम" विधि को कॉल करने का प्रयास करना है:

- (void)viewDidLoad
{
    [super viewDidLoad];
    System * sis = [[System alloc] init];
    [sis printSome];
    //any additional setup after loading the view from its nib.
}

अब मेरे पास निम्न त्रुटि है:

आर्किटेक्चर के लिए अनिर्धारित प्रतीक i386: " OBJC_CLASS $ _System", से संदर्भित: objc-class-ref में "ObjectiveC_Class_That_Call_Swift_Object" .o ld: symbol (s) आर्किटेक्चर के लिए नहीं पाया गया i386 clang: एरर। -v देखने के लिए मंगलाचरण)


आपके पास लिंकर त्रुटि है। क्या यह है: (1) Xcode आपके उत्पाद मॉड्यूल के नाम का उपयोग करता है-न कि आपके लक्षित नाम का - जब उद्देश्य-सी ब्रिजिंग हेडर और आपके स्विफ्ट कोड के लिए उत्पन्न हेडर का नामकरण, या (2) उन लोगों के लिए उद्देश्य-सी हेडर आयात करना सुनिश्चित करें प्रकार स्विफ्ट से उत्पन्न हेडर को ऑब्जेक्टिव-सी .m फाइल में आयात करने से पहले आप किस स्विफ्ट कोड से एक्सेस करना चाहते हैं? क्या आपके पास: आपके उद्देश्य-सी कोड में #import "ProductModuleName-Swift.h" है?
पेट

हाँ, मैंने प्रलेखन पढ़ा है और "ProductModelName" का नाम सही है ... एक बग है कि बिल्ड सेटिंग के अंदर उत्पाद मॉडल सेट नहीं किया गया था ... मैंने इसे सेट भी कर दिया है ...
Eloreden

@petert आप दूसरे बिंदु को बेहतर ढंग से समझा सकते हैं? मैंने लिखा था कभी मैंने किया था ...
Eloreden

प्रॉब्लम सॉल्व्ड, मैंने अपने प्रोजेक्ट कॉल में एक नई .h फाइल को ऐड किया है <ProductModelName> -Swift.h लेकिन यह जरूरी नहीं है क्योंकि कंपाइलर सिर्फ इस ऑब्जेक्ट को बनाते हैं भले ही मैं इसे देख न पाऊं। मैंने अपने द्वारा बनाई गई नई फ़ाइल को हटा दिया है और अब सभी पूरी तरह से चलते हैं। टीएनएक्स पेटर्ट
एलेरडेन

आप अपने खुद के सवालों के जवाब दे सकते हैं - यह दूसरों की मदद कर सकता है।
पेट

जवाबों:


50

समस्या हल हो गई है, मैंने पहले .hअपने ऑब्जेक्टिव-सी वर्ग में एक नई फ़ाइल बनाई और नाम दिया <ProductModuleName>-Swift.h, लेकिन जैसा कि मैंने बाद में पता लगाया, यह कदम आवश्यक नहीं है क्योंकि कंपाइलर आवश्यक फ़ाइल को अदृश्य बनाता है।

बस <ProductModuleName>-Swift.hअपनी कक्षा में शामिल करें और इसे काम करना चाहिए।


3
मापदंडों के साथ कार्यों के बारे में कैसे?
अर्नले विज्केनो

3
मैं स्विफ्ट फ़ंक्शंस को मापदंडों और रिटर्न वैल्यू के साथ एक्सेस करने में सक्षम नहीं हूं, न ही मैं स्विफ्ट फ़ंक्शंस को मापदंडों के बिना और रिटर्न वैल्यू के बिना एक्सेस करने में सक्षम हूं। मुझे पता नहीं क्यों। मेरा स्विफ्ट क्लास एक NSObject है, मैंने फाउंडेशन फ्रेमवर्क को आयात किया, क्लास और फंक्शंस में @objcउपसर्ग है। -Swift.hस्वचालित रूप से बनाया गया है। जो चीज मुझे सिरदर्द बना रही है, वह यह है कि मैं क्लास को ही बुला सकता हूं, लेकिन उसके अंदर कोई फंक्शन नहीं। क्या किसी को पता है क्यों?
डेविड गोल्जूसर


2
यह <productModuleName>-.Swift.h(नहीं model) है।
स्विफ्टआर्किटेक्ट सेप

2
यदि आपके उत्पाद के नाम में कोई स्थान है, तो उन्हें अंडरस्कोर से बदलें, जैसे #import "My_Project-Swift.h":।
EricRobertBrewer

41

यह अजीब है, लेकिन यह काम करेगा

1) Add @objc  to  Swift class

2) Add in .m 
    #import "(ProjectName)-Swift.h"

3) Call from .h
    @class SwiftClass;

4)On SwiftClass 
   click "Command" + Left Click (Apple Documantation)

5) To see "-Swift.h" -> click "Command" + Left Click

App इस वर्ग के लिए इंटरफ़ेस उत्पन्न करेगा -Swift.h

उदाहरण: SWIFT_CLASS ("_ TtC10Project17220PLHelper") @interface PLHelper

  • (शून्य) नोटिफिकेशन डाउनलोडिंग: (NS सहारे *) userInfo;
  • (इंस्टेंटाइप) init OBJC_DESIGNATED_INITIALIZER; @समाप्त

आप अपने स्विफ्ट वर्ग के @objc (MyClassName)
ओबज

12
जो कोई भी मेरे लिए एक ही गूंगा गलती कर सकता है। चरण 2 में, सुनिश्चित करें कि आप उपयोग करते हैं (ProjectName)-Swift.h, नहीं (ClassName)-Swift.h !
१०:०१ बजे हुलंग

धन्यवाद @Svitlana, अविश्वसनीय, यह काम किया !!! लेकिन मुझे कई बार इन चरणों को फिर से अपनाना पड़ता है, जिसमें मेरे जोड़े गए तरीकों को कक्षा में अन्य स्थानों पर ले जाना भी शामिल है।
स्कोफिल्ड ट्रान

1
3) @class SwiftClassName;मुझे बचाया
माज़ेन कासेर

33

मान लें कि हमारे पास ProjectName "MyFirstProjectOnSwift" और स्विफ्ट क्लास का नाम "mySwiftClass" और वस्तुनिष्ठ वर्ग "MyObjectiveCLass" है

निम्नलिखित चरण हैं: -

  1. "MyObjectiveCL.m" में #import "MyFirstProjectOnSwift-Swift.h" जोड़ें

  2. MyObjectiveCLass.h में @class mySwiftClass जोड़ें;

  3. फिर MyObjectiveCLass.m में

    mySwiftClass * myClass = [mySwiftClass new]; {जहां भी आप स्विफ्ट विधि से कॉल करना चाहते हैं किसी भी तरीके से इस तरह कॉल करें। "

  4. [myClass methodName];


2
mySwiftClass * myClass = [mySwiftClass new] इसका मेरे लिए काम नहीं करना >>>>>
हरि नारायणन

@ हरिनारायणन यह नहीं होना चाहिए, एक स्पष्ट डेटा प्राप्त करें और अपनी परियोजना को फिर से खोलें।
शुभ गिरि

12

जाँच करें -Swift.h फ़ाइल जो कि आपके .m फ़ाइल पर इंपोर्ट-सी में है:

#import <YourProjectName-Swift.h>

उस लाइन पर क्लिक करें, और बाएं क्लिक करें - जंप टू डेफिनिशन।

इस फ़ाइल को स्वचालित रूप से शामिल किया जाना चाहिए, मैन्युअल रूप से नहीं।


2

यदि आप आयात करने के बाद भी अपनी कक्षा नहीं देख रहे हैं <ProductModuleName>-Swift.h

सुनिश्चित करें कि आपकी कक्षा एक मूल वर्ग (जैसे UIViewController) या कम से कम एक उपवर्ग है, यदि यह सिर्फ एक उपयोगिता वर्ग है, तो इसे उपवर्ग बनाएं NSObject। अब आपकी क्लास दिखनी चाहिए।


2

इस पद पर ठोकर खाने वाले किसी भी व्यक्ति के लिए थोड़ा अतिरिक्त टिप और अन्य उत्तरों के लिए काम नहीं करता है: आपको अपनी स्विफ्ट क्लास को "सार्वजनिक" भी घोषित करना पड़ सकता है।

उदाहरण:

@objc public class MySwiftClass: NSObject {


0

ओबज-सी से स्विफ्ट में माइग्रेट किए जा रहे प्रोजेक्ट्स पर ऑब्जेक्टिव-सी से स्विफ्ट कोड को निष्पादित करने के लिए पुनःप्राप्त तरीका ब्रिज / प्रॉक्सी पैटर्न का उपयोग कर रहा है।

  1. पुल को लागू करें।

import Foundation

@objc class AnalyticsPropertyBridge: NSObject {

private var analytics: AnalyticsManager = AnalyticsManager()

@objc func refreshProperties() {

    self.analytics.set(AnalyticsProperty.clientType)
}

}

  1. छाता फ़ाइल (ब्रिजिंग-हैडर) में objC कॉलर मॉड्यूल शामिल करें:

#import "CallerModule.h"

  1. अंत में कॉलर .m फ़ाइल में, दो समस्याएँ:

3.a आयात छाता फ़ाइल:

#import "MyProject-Swift.h"

3.b पुल को बुलाओ।

[[AnalyticsPropertyBridge new] refreshProperties];

लाभ: आपका स्विफ्ट कोड @objc से गंदा नहीं होगा क्योंकि ओबजैक से कोड कहा जा रहा है। जैसे-जैसे समय बीतता जाएगा, आपकी परियोजना में ओबीजीसी कम हो जाएगा और अंत में दुल्हन को हटा दिया जाएगा।


-1

एक अच्छा लेख यहाँ अगर किसी को अभी भी समस्या है।

स्विफ्ट और ऑब्जेक्टिव-सी इंटरऑपरेबिलिटी की स्थापना

  1. इस लेख में गहराई से चर्चा की गई है कि स्विफ्ट फाइलों को ओबीजीसी में कैसे आयात किया जाए और साथ ही ओब्जैक फाइलों को स्विफ्ट को भी भेजा जाए।
  2. यह आमतौर पर उस प्रॉब्लम को भी संबोधित करता है जब प्रोजेक्ट नाम में जगह होती है।
  3. यह "उत्पाद मॉड्यूल नाम" ध्वज के बारे में भी चर्चा करता है।

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