Objective-C 클래스에서 Swift 함수 호출


84

이전 Objective-C 프로젝트가 있고 새 Swift 함수와 개체를 호출하고 싶습니다. " <ProjectName>-Bridging-Header.h"및 " <ProjectName>-Swift.h" 파일을 만들었습니다.

Swift에서 Objective-C로 함수를 호출하기는 쉬웠지만 반대로 문제가 있습니다.

그래서 간단한 클래스 "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 클래스 내에서 가져 왔습니다. 이 시점에서 내 Objective-C 코드의 Objective C 클래스 (현재 UIViewController) 내에서 "printSome"메서드를 호출하려고했습니다.

- (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", 참조 : "ObjectiveC_Class_That_Call_Swift_Object"의 objc-class-ref : 아키텍처 i386에 대한 기호를 찾을 수 없음 clang : 오류 : 링커 명령이 종료 코드 1로 실패했습니다 (사용 -v 호출 참조)


링커 오류가 있습니다. (1) Xcode는 Objective-C 브리징 헤더와 Swift 코드에 대해 생성 된 헤더의 이름을 지정할 때 대상 이름이 아닌 제품 모듈 이름을 사용합니다. 또는 (2) 해당 대상에 대한 Objective-C 헤더를 가져와야합니다. Swift에서 생성 된 헤더를 Objective-C .m 파일로 가져 오기 전에 Swift 코드에 액세스하려는? Objective-C 코드에 #import“ProductModuleName-Swift.h”가 있습니까?
petert

예, 문서를 읽었으며 "ProductModelName"의 이름이 현재입니다 ... 빌드 설정 내에 제품 모델이 설정되지 않은 버그가 있습니다 ... 심지어 설정했습니다 ...
Eloreden

@petert 두 번째 요점을 더 잘 설명 할 수 있습니까? 내가 ... 내가 한 everithing 쓴
Eloreden

문제 해결, 내 프로젝트 호출 <ProductModelName> -Swift.h에 새 .h 파일을 추가했지만 컴파일러가이 개체를 볼 수없는 경우에도 생성하기 때문에 필요하지 않습니다. 내가 만든 새 파일을 삭제했으며 이제 모두 완벽하게 실행됩니다. Tnx petert
Eloreden 2014-06-06

자신의 질문에 답할 수 있습니다. 다른 사람에게 도움이 될 수 있습니다.
petert 2014-06-06

답변:


50

문제가 해결되었습니다. 이전에 Objective-C 클래스 .h에 새 파일을 만들고 포함 시켰지만 나중에 발견 했듯이 컴파일러가 필요한 파일을 보이지 않게 만들기 때문에이 단계가 필요하지 않습니다.<ProductModuleName>-Swift.h

<ProductModuleName>-Swift.h수업에 포함 하기 만하면 작동합니다.


3
매개 변수가있는 함수는 어떻습니까?
Arnlee Vizcayno 2014 년

3
매개 변수와 반환 값이있는 Swift 함수에 액세스 할 수 없으며 매개 변수없이 반환 값없이 Swift 함수에 액세스 할 수 없습니다. 이유를 모르겠습니다. 내 Swift Class는 NSObject이고 Foundation 프레임 워크를 가져 왔고 클래스와 함수에는 @objc접두사가 있습니다. 이 -Swift.h자동으로 생성되었습니다. 나를 괴롭히는 것은 Class 자체를 호출 할 수는 있지만 내부 함수는 호출 할 수 없다는 것입니다. 이유를 아는 사람이 있습니까?
David Gölzhäuser 2014 년


2
그것은이다 <productModuleName>-.Swift.h(하지 model).
SwiftArchitect 2015-09-13

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

앱은 -Swift.h에서이 클래스에 대한 인터페이스를 생성합니다.

예 : SWIFT_CLASS ( "_ TtC10Project17220PLHelper") @interface PLHelper

  • (무효) notifyForDownloading : (NSDictionary *) userInfo;
  • (인스턴스 유형) init OBJC_DESIGNATED_INITIALIZER; @종료

다음을 사용하여 Swift 클래스의 Obj-C 이름을 재정의 할 수도 있습니다.@objc (MyClassName)
nielsbot dec

12
나와 같은 바보 같은 실수를 할 수있는 사람을 위해. 2 단계에서 (ProjectName)-Swift.h, NOT (ClassName)-Swift.h !
Hlung

감사합니다 @Svitlana, 믿을 수없는 일이었습니다! 그러나 추가 된 메서드를 클래스의 다른 위치로 이동하는 것을 포함하여 이러한 단계를 여러 번 다시 시도해야합니다.
스코필드 트란

1
3) @class SwiftClassName;나 저장
마젠 Kasser

33

ProjectName "MyFirstProjectOnSwift"와 신속한 클래스 이름 "mySwiftClass"가 있고 objectiveC 클래스가 "MyObjectiveCLass"라고 가정합니다.

다음 단계는 다음과 같습니다.

  1. "MyObjectiveCLass.m"에 #import "MyFirstProjectOnSwift-Swift.h"를 추가합니다.

  2. MyObjectiveCLass.h에 @class mySwiftClass를 추가합니다.

  3. 그런 다음 MyObjectiveCLass.m에서

    mySwiftClass * myClass = [mySwiftClass new]; {빠른 메소드를 호출하려는 모든 메소드에서 이와 같이 호출하십시오.}

  4. [myClass methodName];


2
mySwiftClass * myClass가 = [mySwiftClass 새]는하지 >>>>> 나를 위해 일
하리 나라 야난

@HariNarayanan 그렇게해서는 안됩니다. 명확한 파생 데이터를 생각하고 프로젝트를 다시여십시오.
Anubhav 기리

12

Objective-C에서 .m 파일에 가져 오기가있는 -Swift.h 파일을 확인하십시오.

#import <YourProjectName-Swift.h>

해당 줄을 클릭하고 왼쪽 클릭-정의로 이동.

이 파일은 수동이 아닌 자동으로 포함되어야합니다.


2

를 가져온 후에도 여전히 수업이 표시되지 않는 경우 <ProductModuleName>-Swift.h.

클래스가 네이티브 클래스 (예 :)를 서브 클래 싱하고 있는지 확인 UIViewController하거나 적어도 유틸리티 클래스 인 경우 하위 클래스로 만듭니다 NSObject. 이제 수업이 표시됩니다.


2

이 게시물에 걸려 넘어지는 사람을위한 약간의 추가 팁과 다른 답변은 작동하지 않습니다. Swift 클래스를 "public"으로 선언해야 할 수도 있습니다.

예:

@objc public class MySwiftClass: NSObject {


0

Obj-C에서 Swift로 마이그레이션되는 프로젝트에서 Objective-C에서 Swift 코드를 실행하는 권장 방법은 Bridge / Proxy 패턴을 사용하는 것입니다.

  1. Bridge를 구현하십시오.

import Foundation

@objc class AnalyticsPropertyBridge: NSObject {

private var analytics: AnalyticsManager = AnalyticsManager()

@objc func refreshProperties() {

    self.analytics.set(AnalyticsProperty.clientType)
}

}

  1. 우산 파일 (Bridging-Header)에 objC 호출자 모듈을 포함합니다.

#import "CallerModule.h"

  1. 마지막으로 호출자 .m 파일에서 두 가지 문제가 있습니다.

3.a 우산 파일 가져 오기 :

#import "MyProject-Swift.h"

3.b 브리지를 호출합니다.

[[AnalyticsPropertyBridge new] refreshProperties];

이점 : 코드가 Objc에서 호출되기 때문에 신속한 코드가 @objc로 더러워지지 않습니다. 시간이 지남에 따라 프로젝트에서 ObjC가 줄어들고 마침내 신부가 제거됩니다.


-1

누군가 여전히 문제가있는 경우 여기에 좋은 기사입니다.

Swift 및 Objective-C 상호 운용성 설정

  1. 이 기사에서는 Swift 파일을 ObjC로 가져오고 Objc 파일을 Swift로 가져 오는 방법에 대해 자세히 설명합니다.
  2. 또한 프로젝트 이름에 공백이있을 때 일반적으로 직면하는 문제를 해결합니다.
  3. 또한 "제품 모듈 이름"플래그에 대해서도 설명합니다.

이 이론적으로 질문에 대답 할 수 있습니다 동안, 바람직 할 것이다 여기에 대한 대답의 본질적인 부분을 포함하고 참조 할 수 있도록 링크를 제공합니다.
Arghya Sadhu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.