Objective-C 클래스에서 Swift 프로토콜 가져 오기


116

라는 AnalyticProtocolObjective-C 클래스로 명명 된 Swift 프로토콜을 가져 오려고합니다 AnalyticFactory.

protocol AnalyticProtocol
{

}

기존 Objective-C 프로젝트에서 시작하고 있습니다 (xCode로 새 Swift 프로젝트를 만들지 않았고 Objective-C 프로젝트를 xCode 6에서 Swift 프로젝트로 구성하는 방법을 찾지 못했습니다 ).

내 Swift 파일에 .h이름이 지정된 파일을 포함 MyProjectName-Swift.h했지만 컴파일러 가 존재하지 않는다는 오류를 반환 합니다 . 그래서 실제로 비어있는 .h이름 의 파일을 만들었습니다 MyProjectName-Swift.h(무엇을 넣어야할지 모르겠습니다).

에서 애플 문서 그들은 내가 내 포함 할 필요가 있다고 말했다 .h지정된 파일 MyProjectName-Swift.h내에서 .m파일을. 하지만 내 .m파일이 아니라 내 .h. 이것이 문제가 될 수 있습니까?

컴파일을 시도 할 때 다음 오류가 발생합니다. : 0 : 오류 : xxxAnalyticFactory.h : 39 : 'AnalyticProtocol'에 대한 프로토콜 선언을 찾을 수 없습니다.

그리고 기소 된 코드 :

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

Swift 프로토콜을 Objective-C 클래스로 가져올 수있는 방법을 잘 이해하지 못하는 것 같습니다.

내가하는 일에 오류가있는 사람이 있습니까?


WWDC 2014 의 Integrating Swift With Objective-C 비디오를 확인하십시오 . 비디오의 약 30:40에 Objective-C 클래스에서 Swift 프로토콜에 액세스하는 방법을 설명합니다.
Jamie Forrest

답변:


224

다음 @objc과 같이 Swift 프로토콜에 속성 을 추가해야합니다 .

@objc protocol AnalyticProtocol {

}

25
답변 해 주셔서 감사하지만 문제는 여전히 지속됩니다.
Jean Lebrument 2014-06-06

문제를 재현하는 샘플 프로젝트를 게시 할 수 있습니까?
Jamie Forrest

@objc를 추가하면 Obj-C로 Swift 클래스를 가져 오는 데 도움이되었습니다
serg

19
@objc가 항상 작동하는 것은 아닙니다. 프로토콜을 준수 할 때 파일 에 프로토콜을 추가 할 때 작동하지 않는 경우 @interface.h있습니다. 그러나 프로토콜을 파일 의 개인 @interface에 추가 할 수 .m있으며 문제가 해결됩니다 (적어도 가끔은 저에게 있음). 그래서 위 @implementation있다 @interface MyController() <AnalyticProtocol>.
아담

1
편집하는 동안 때때로 Xcode 8이 불평하지만 실제로 빌드하면 주석과 함께이 답변을 따르면 오류가 사라집니다.
Roger Pingleton 2016 년

77

objC 헤더 파일에서 Xcode 생성 Swift 헤더를 가져올 수 없습니다.

따라서 objC 헤더 파일에서 Swift 코드를 사용하려면 다음과 같이 objC 헤더 파일에서 사용하려는 클래스와 프로토콜을 "전달 선언"해야합니다.

@protocol AnalyticProtocol;

이제 objC 클래스 선언에서 프로토콜을 사용할 수 있습니다.

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

구현 파일 (objC .m 파일)에서 Xcode에서 생성 한 Swift 헤더 ( "ProductModuleName-Swift.h") 파일을 가져올 수 있으며 올바른 구현 AnalyticProtocol이 이제 컴파일러에 알려집니다.

이것은 Apple Docs의 "Using Swift from Objective-C"섹션에도 설명되어 있습니다.

XCode는 앞으로 선언 된 프로토콜 ( "AnalyticProtocol에 대한 프로토콜 정의를 찾을 수 없음 ')을 사용할 때 objC 헤더 파일에 경고를 표시하지만 무시할 수 있습니다. 구현은 컴파일 타임에 발견됩니다.


19
Xcode가 컴파일되고 제대로 작동 할 때 프로토콜 누락에 대한 경고를 표시하는 이유는 무엇입니까? 경고를 제거 할 방법이 있습니까?
Oren

그래도이 클래스에서 프로토콜 메서드를 호출 할 수는 없습니다. 그것은 오류 줄 것이다No visible @interface for <ClassName> declares the selector <protocolMethodName>
엘사

다음 경고를 생성합니다. "xxxx에 대한 프로토콜 정의를 찾을 수 없습니다."
JAHelia

51

단순히 프로토콜을 채택해야하는 모든 사용자를 위해 경고 나 오류를 생성하지 않고 두 단계로 수행 할 수 있습니다.

  1. 당신에 .swift파일 추가, @objc프로토콜 이름 앞에 :

    @objc protocol AnalyticProtocol {
    
    }
  2. 당신에 .m파일을 생성 스위프트 헤더를 가져 오기 및 민간 부문에서 프로토콜을 채택한다. (헤더 파일은 자동으로 이름이 지정됩니다) :

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

이것이 Apple에서 권장하는 접근 방식입니다. Objective-C와 Swift의 믹싱 및 매칭에 대한 자세한 내용은 https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html에서 확인할 수 있습니다.


1
전진 선언 여부에 관계없이 여전히 경고를받습니다. 확장 프로그램에서 프로토콜을 사용하고 있습니다.
Cristi Băluță

을 (를) 가져올 수 없습니다 #import "AnalyticProtocol-Swift.h". WhateverProtocol-Swift.h가 말한대로 자동 생성되지 않은 것 같습니다.
Hlung

2
이것은 나를 위해 일했습니다. 이 페이지의 다른 제안이나 답변은 작동하지 않았습니다. 나는 스위프트 4. 해요
폴스 보 (Poulsbo)

1
이것은 경고를 제거하는 유일한 방법이었습니다 (프로토콜이 헤더 파일에있을 때 작동하더라도)
David P

1
같은 링크는 WebArchive를 통해 볼 수 있습니다 : web.archive.org/web/20170310053717/https://developer.apple.com/...
리처드 Topchii

3

프레임 워크를 만드는 경우 필요한 가져 오기

#import "ProductModuleName-Swift.h"

변경 사항 :

#import <ProductModuleName/ProductModuleName-Swift.h>

이 경우 빠른 프로토콜을 공개 해야합니다 .

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

3

코드를 거의 변경하지 않고 Objective C에서 신속한 프로토콜을 사용할 수 있습니다. 또한 @objc 선언 프로토콜을 사용하면 기본 구현없이 선택적 및 필수 메서드를 사용할 수 있습니다. 장단점이 있습니다.

Objective C에서 사용할 때 실제로 프로토콜 이름을보다 설명적인 이름으로 바꿀 수 있습니다. 저는 "@objc (alias_name)"을 사용합니다.

다음은 코드입니다. ObjC 코드에서 사용할 @objc 속성과 별칭 이름을 사용하는 신속한 프로토콜을 만들어 보겠습니다.

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

이제 farword가 .h 파일에서 프로토콜을 선언 해 보겠습니다.

@protocol ObjTableViewReloadable;

이제 .m 파일에서이 프로토콜을 준수하고 필요한 메소드 구현을 추가 할 수 있습니다.

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

게시 해주셔서 감사합니다. 나는 흙보다 오래된 레거시 코드를보고 있는데이 접근 방식이 효과가 있다면 엄청난 고통을 덜어 줄 것입니다. :)
Adrian
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.