[ios] Objective-C에서 Swift 클래스를 사용할 수 없습니다

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. 그래서 나는 새로운 XcodeObjc 기반 프로젝트 를 만들기로 결정 했고 마침내 정답을 찾았습니다! 이 게시물이 누군가를 도울 수 있기를 바랍니다 🙂

Xcode Objc 기반 프로젝트를위한 단계별 Swift 통합 :

  1. *.swiftXcode에서 새 파일을 생성 하거나 Finder를 사용하여 추가하십시오.
  2. Objective-C bridging headerXcode가 그것에 대해 물을 때를 만드십시오 .
  3. Swift 클래스를 구현하십시오.

    import Foundation
    
    // use @objc or @objcMembers annotation if necessary
    class Foo {
        //..
    }
    
  4. 빌드 설정을 열고 다음 매개 변수를 확인하십시오.

    • 모듈을 정의합니다 : YES

      검색 창에 매개 변수 이름 복사 및 붙여 넣기

    • 제품 모듈 이름 : myproject

      제품 모듈 이름에 특수 문자가 포함되어 있지 않은지 확인하십시오

    • Objective-C 호환성 헤더를 설치하십시오. YES

      *.swift프로젝트 에 파일을 추가하면 이 속성이 빌드 설정에 나타납니다

    • Objective-C 생성 인터페이스 헤더 : myproject-Swift.h

      이 헤더는 Xcode에 의해 자동 생성됩니다

    • 오브젝티브 -C 브리징 헤더 : $(SRCROOT)/myproject-Bridging-Header.h
  5. * .m 파일에서 Swift 인터페이스 헤더를 가져옵니다.

    #import "myproject-Swift.h"

    오류 및 경고에주의하지 마십시오.

  6. Xcode 프로젝트를 정리하고 다시 빌드하십시오.
  7. 이익!

답변

헤더 파일을 직접 만들지 마십시오. 만든 것을 삭제하십시오.

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 프로젝트

작업 :

  1. objective-c 클래스에서 swift enum 사용
  2. 신속한 클래스에서 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설정에서 모듈을 사용 하거나 이름을 바꿉니다.