iOS

Framework 프로젝트의 ObjC 클래스에서 Swift Public 클래스 사용하기

Phililip 2024. 10. 27.
728x90

안녕하세요.

 

이번엔 framework 프로젝트 안에 있는 Objective-C 클래스가 Swift 코드를 사용할 수 있는 방법을 간단하게 정리해 볼까 해요.

 


# 필수 설정

Objective-C에서 Swift 모듈을 사용하려면, Swift는 반드시 NSObject를 상속받은 클래스여야 하며, 클래스에 @objc 또는 @objecMembers 속성이 있어야 합니다.

 

@objc public class MySwiftClass: NSObject {
// ...
}

 

# Swift Public 클래스의 Public 메서드, 프로퍼티 사용하는 방법

1) public 메서드 또는 프로퍼티에 @objc 설정 추가

 

@objc public class MySwiftClass: NSObject {
@objc public var publicProperty: String = "This is public"
@objc public func publicMethod() {
// Do something
}
}

 

2) {Framework}-Swift.h 헤더를 import 후 사용

 

#import <MyFramework/MyFramework-Swift.h>
@interface MyObjCClass: NSObject
- (void)someMethod;
@end
@implementation MyObjCClass
- (void)someMethod {
MySwiftClass *swiftClass = [[MySwiftClass alloc] init];
NSString *value = swiftClass.publicProperty;
[swiftClass publicMethod];
}
@end
view raw MyObjCClass.m hosted with ❤ by GitHub

 

# Swift Public 클래스의 Internal 메서드, 프로퍼티 사용하는 방법

Framework 환경에선 Bridging Header가 지원되지 않기 때문에 Internal level을 호출하려면 몇 가지 스텝이 추가되어야 합니다.

 

1) Internal 메서드 또는 프로퍼티에 @objc 설정 추가

 

@objc public class MySwiftClass: NSObject {
@objc var internalProperty: String = "This is internal"
@objc func internalMethod() {
// Do something
}
}

 

2) Objective-C에서 Swift 클래스의 internal 메서드와 프로퍼티를 참조할 수 있도록 Swift 클래스와 동일한 스펙의 프로토콜 추가

 

//
// OBJC_MySwiftClassProtocol.h
// MyFramework
//
//
#ifndef OBJC_MySwiftClassProtocol_h
#define OBJC_MySwiftClassProtocol_h
/*
Objective-C에서 Swift 클래스의 internal level의 메서드와 프로퍼티를 참조할 수 있도록 Swift 클래스에 정의된 대로 프로토콜 정의
*/
SWIFT_PROTOCOL_NAMED("MySwiftClassProtocol")
@protocol OBJC_MySwiftClassProtocol <NSObject>
@property (nonatomic, strong) NSString *internalProperty;
- (void)internalMethod;
@end
#endif /* OBJC_MySwiftClassProtocol_h */

 

3) Objective-C에서 컴파일 타임 참조가 가능하도록 Swift 클래스에 카테고리 추가하여 프로토콜 채택

 

//
// MySwiftClass+ObjC.h
// MyFramework
//
//
#ifndef MySwiftClass_ObjC_h
#define MySwiftClass_ObjC_h
#import "OBJC_MySwiftClassProtocol.h"
/*
Objective-C에서 컴파일 타임 참조가 가능하도록 Swift 클래스에 카테고리 추가 후 프로토콜 채택
*/
@interface MySwiftClass (ObjC) <OBJC_MySwiftClassProtocol>
@end
#endif /* MySwiftClass_ObjC_h */

 

4) {Framework}-Swift.h 헤더와 위에 추가한 카테고리가 있는 헤더파일을 import 후 사용

 

#import "MyObjCClass.h"
#import <MyFramework/MyFramework-Swift.h>
#import "MySwiftClass+ObjC.h"
@interface MyObjCClass: NSObject
- (void)someMethod;
@end
@implementation MyObjCClass
- (void)someMethod {
MySwiftClass *swiftClass = [[MySwiftClass alloc] init];
NSString *value = swiftClass.internalProperty;
[swiftClass internalMethod];
}
@end
view raw MyObjCClass.m hosted with ❤ by GitHub
[참고] 왜 Internal level은 public level과 다르게 {Framework}-Swift.h 헤더를 추가해도 Objective-C 컴파일 타임 때 참조가 불가능한가요?

{Framework}-Swift.h 헤더는 Xcode가 생성한 프레임워크의 공개 Interface이기 때문에 public 또는 open으로 표시된 선언만이 헤더에 나타납니다.

그렇기 때문에, Swift 코드 내에 Internal로 선언된 것들은 헤더에 포함되지 않기 때문에 런타임 참조는 가능하지만 컴파일 타임 참조는 불가능합니다.

 

# 참고

 

Importing Swift into Objective-C | Apple Developer Documentation

Access Swift types and declarations from within your Objective-C codebase.

developer.apple.com

 


이번 글은 여기서 마무리.

 

 

 

반응형