Swift
내 앱에 코드 를 통합하려고하는데 내 앱이 작성되고 클래스가 Objective-C
추가되었습니다 Swift
. 나는 여기에 설명 된 모든 것을 다 했다 . 그러나 내 문제는 파일을 Xcode
만들지 않고 -Swift.h
브리징 헤더 만 생성 한다는 것 입니다. 그래서 나는 그것을 만들었지 만 실제로 비어 있습니다. Swift에서 모든 ObjC 클래스를 사용할 수 있지만 그 반대도 할 수 없습니다. 나는 빠른 수업을 표시 @objc
했지만 도움이되지 않았습니다. 내가 지금 무엇을 할 수 있을까?
편집 : 애플은 말합니다 : “스위프트 코드를 Objective-C로 가져올 때, 당신은 Xcode-generated
파일을 Objective-C에 노출시키기 위해 헤더 파일 에 의존합니다 . […]이 헤더의 이름은 제품 모듈 이름이며” -Swift.h”. “
이제 해당 파일을 가져 오려면 오류가 발생합니다.
//MainMenu.m
#import "myProjectModule-Swift.h" //Error: 'myProjectModule-Swift.h' file not found
@implementation MainMenu
내 FBManager.swift 파일은 다음과 같습니다.
@objc class FBManager: NSObject {
var descr = "FBManager class"
init() {
super.init()
}
func desc(){
println(descr)
}
func getSharedGameState() -> GameState{
return GameState.sharedGameState() //OK! GameState is written in Objective-C and no error here
}
}
답변
Objective-C 기반 프로젝트 Swift
에서 활성화하는 데 약 4 시간이 걸렸습니다 Xcode
. myproject-Swift.h
파일이 성공적으로 생성되었지만 내 파일이 Xcode
보이지 않습니다 Swift-classes
. 그래서 나는 새로운 Xcode
Objc 기반 프로젝트 를 만들기로 결정 했고 마침내 정답을 찾았습니다! 이 게시물이 누군가를 도울 수 있기를 바랍니다 🙂
Xcode Objc 기반 프로젝트를위한 단계별 Swift 통합 :
*.swift
Xcode에서 새 파일을 생성 하거나 Finder를 사용하여 추가하십시오.Objective-C bridging header
Xcode가 그것에 대해 물을 때를 만드십시오 .-
Swift 클래스를 구현하십시오.
import Foundation // use @objc or @objcMembers annotation if necessary class Foo { //.. }
-
빌드 설정을 열고 다음 매개 변수를 확인하십시오.
- 모듈을 정의합니다 :
YES
검색 창에 매개 변수 이름 복사 및 붙여 넣기
- 제품 모듈 이름 :
myproject
제품 모듈 이름에 특수 문자가 포함되어 있지 않은지 확인하십시오
- Objective-C 호환성 헤더를 설치하십시오.
YES
*.swift
프로젝트 에 파일을 추가하면 이 속성이 빌드 설정에 나타납니다 - Objective-C 생성 인터페이스 헤더 :
myproject-Swift.h
이 헤더는 Xcode에 의해 자동 생성됩니다
- 오브젝티브 -C 브리징 헤더 :
$(SRCROOT)/myproject-Bridging-Header.h
- 모듈을 정의합니다 :
-
* .m 파일에서 Swift 인터페이스 헤더를 가져옵니다.
#import "myproject-Swift.h"
오류 및 경고에주의하지 마십시오.
- Xcode 프로젝트를 정리하고 다시 빌드하십시오.
- 이익!
답변
헤더 파일을 직접 만들지 마십시오. 만든 것을 삭제하십시오.
Swift 클래스가 @objc
에서 (직접 또는 간접적으로) 파생 된 클래스로 태그 되거나 상속 된 클래스인지 확인하십시오 NSObject
.
프로젝트에 컴파일러 오류가 있으면 Xcode에서 파일을 생성하지 않습니다. 프로젝트가 올바르게 빌드되었는지 확인하십시오.
답변
Xcode가 작동하도록 허용하고 Swift 헤더를 수동으로 추가 / 생성하지 마십시오. Swift 클래스 ex 전에 @objc를 추가하십시오.
@objc class YourSwiftClassName: UIViewController
프로젝트 설정에서 아래 플래그를 검색하고 YES로 변경하십시오 (프로젝트 및 대상 모두)
Defines Module : YES
Always Embed Swift Standard Libraries : YES
Install Objective-C Compatibility Header : YES
그런 다음 빌드가 성공한 후 프로젝트를 정리하고 한 번 빌드하십시오 (아마도 objective-c class .m 파일의 헤더 파일 아래로 가져와야 함)
#import "YourProjectName-Swift.h"
oooo!
답변
또한 Framework 대상 이있는 사람들에게 도움이 될 것입니다 .
자동 생성 된 헤더 파일 의 import 문 은 앱 대상과 약간 다릅니다 . 다른 답변에 언급 된 다른 것들 외에도
#import <ProductName/ProductModuleName-Swift.h>
대신에
#import "ProductModuleName-Swift.h"
프레임 워크 대상에 대한 믹스 앤 매치 에 관한 Apple 문서에 따라 .
답변
프로젝트가 모듈을 정의하고 모듈에 이름을 지정했는지 확인하십시오. 그런 다음 다시 빌드하면 Xcode가 -Swift.h
헤더 파일 을 작성하고 가져올 수 있습니다.
프로젝트 설정에서 모듈 정의 및 모듈 이름을 설정할 수 있습니다.
답변
세부 사항 : Xcode 8.1에서 Swift 3 코드가있는 Objective-C 프로젝트
작업 :
- objective-c 클래스에서 swift enum 사용
- 신속한 클래스에서 objective-c enum 사용
전체 샘플
1. Swift 열거 형을 사용하는 Objective-C 클래스
ObjcClass.h
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, ObjcEnum) {
ObjcEnumValue1,
ObjcEnumValue2,
ObjcEnumValue3
};
@interface ObjcClass : NSObject
+ (void) PrintEnumValues;
@end
ObjcClass.m
#import "ObjcClass.h"
#import "SwiftCode.h"
@implementation ObjcClass
+ (void) PrintEnumValues {
[self PrintEnumValue:SwiftEnumValue1];
[self PrintEnumValue:SwiftEnumValue2];
[self PrintEnumValue:SwiftEnumValue3];
}
+ (void) PrintEnumValue:(SwiftEnum) value {
switch (value) {
case SwiftEnumValue1:
NSLog(@"-- SwiftEnum: SwiftEnumValue1");
break;
case SwiftEnumValue2:
case SwiftEnumValue3:
NSLog(@"-- SwiftEnum: long value = %ld", (long)value);
break;
}
}
@end
Objective-C 코드에서 스위프트 코드 감지
내 샘플에서는 SwiftCode.h를 사용하여 Objective-C에서 Swift 코드를 감지합니다. 이 파일은 자동으로 생성되며 (프로젝트에서이 헤더 파일의 실제 복사본을 만들지 않았습니다)이 파일의 이름 만 설정할 수 있습니다.
컴파일러가 헤더 파일 Swift 코드를 찾을 수 없으면 프로젝트를 컴파일하십시오.
Objective-C 열거 형을 사용하는 Swift 클래스
import Foundation
@objc
enum SwiftEnum: Int {
case Value1, Value2, Value3
}
@objc
class SwiftClass: NSObject {
class func PrintEnumValues() {
PrintEnumValue(.Value1)
PrintEnumValue(.Value2)
PrintEnumValue(.Value3)
}
class func PrintEnumValue(value: ObjcEnum) {
switch value {
case .Value1, .Value2:
NSLog("-- ObjcEnum: int value = \(value.rawValue)")
case .Value3:
NSLog("-- ObjcEnum: Value3")
break
}
}
}
Swift 코드에서 Objective-C 코드 감지
브리징 헤더 파일을 만들어야합니다. Objective-C 프로젝트에 Swift 파일을 추가하거나 신속한 프로젝트에 Objective-C 파일을 추가하면 Xcode에서 브리징 헤더를 생성하도록 제안합니다.
여기에서 브리징 헤더 파일 이름을 변경할 수 있습니다.
브리징 헤더 .h
#import "ObjcClass.h"
용법
#import "SwiftCode.h"
...
[ObjcClass PrintEnumValues];
[SwiftClass PrintEnumValues];
[SwiftClass PrintEnumValue:ObjcEnumValue3];
결과
더 많은 샘플
전체 통합은 목표 – C 단계와 스위프트는 전술 . 이제 다른 코드 예제를 작성하겠습니다.
3. Objective-c 코드에서 Swift 클래스 호출
스위프트 클래스
import Foundation
@objc
class SwiftClass:NSObject {
private var _stringValue: String
var stringValue: String {
get {
print("SwiftClass get stringValue")
return _stringValue
}
set {
print("SwiftClass set stringValue = \(newValue)")
_stringValue = newValue
}
}
init (stringValue: String) {
print("SwiftClass init(String)")
_stringValue = stringValue
}
func printValue() {
print("SwiftClass printValue()")
print("stringValue = \(_stringValue)")
}
}
Objective-C 코드 (호출 코드)
SwiftClass *obj = [[SwiftClass alloc] initWithStringValue: @"Hello World!"];
[obj printValue];
NSString * str = obj.stringValue;
obj.stringValue = @"HeLLo wOrLd!!!";
결과
4. 스위프트 코드에서 Objective-c 클래스 호출
Objective-C 클래스 (ObjcClass.h)
#import <Foundation/Foundation.h>
@interface ObjcClass : NSObject
@property NSString* stringValue;
- (instancetype) initWithStringValue:(NSString*)stringValue;
- (void) printValue;
@end
ObjcClass.m
#import "ObjcClass.h"
@interface ObjcClass()
@property NSString* strValue;
@end
@implementation ObjcClass
- (instancetype) initWithStringValue:(NSString*)stringValue {
NSLog(@"ObjcClass initWithStringValue");
_strValue = stringValue;
return self;
}
- (void) printValue {
NSLog(@"ObjcClass printValue");
NSLog(@"stringValue = %@", _strValue);
}
- (NSString*) stringValue {
NSLog(@"ObjcClass get stringValue");
return _strValue;
}
- (void) setStringValue:(NSString*)newValue {
NSLog(@"ObjcClass set stringValue = %@", newValue);
_strValue = newValue;
}
@end
스위프트 코드 (호출 코드)
if let obj = ObjcClass(stringValue: "Hello World!") {
obj.printValue()
let str = obj.stringValue;
obj.stringValue = "HeLLo wOrLd!!!";
}
결과
5. Objective-c 코드에서 Swift 확장 사용
스위프트 확장
extension UIView {
static func swiftExtensionFunc() {
NSLog("UIView swiftExtensionFunc")
}
}
Objective-C 코드 (호출 코드)
[UIView swiftExtensionFunc];
6. 신속한 코드에서 Objective-c 확장 사용
Objective-C 확장 (UIViewExtension.h)
#import <UIKit/UIKit.h>
@interface UIView (ObjcAdditions)
+ (void)objcExtensionFunc;
@end
UIViewExtension.m
@implementation UIView (ObjcAdditions)
+ (void)objcExtensionFunc {
NSLog(@"UIView objcExtensionFunc");
}
@end
스위프트 코드 (호출 코드)
UIView.objcExtensionFunc()
답변
나는 같은 문제를 겪었고 모듈 이름의 특수 기호가 xcode로 대체되었습니다 (내 경우 대시는 밑줄이되었습니다). 프로젝트 설정에서 “모듈 이름”을 확인하여 프로젝트의 모듈 이름을 찾으십시오. 그런 다음 ModuleName-Swift.h
설정에서 모듈을 사용 하거나 이름을 바꿉니다.