수색…


비고

더 자세한 정보는 Sweet와 Cocoa 및 Objective-C 사용 에 대한 Apple의 설명서를 참조하십시오.

Objective-C 코드의 Swift 클래스 사용

동일한 모듈에서

" MyModule "이라는 모듈 내에서 Xcode는 공용 Swift 클래스를 Objective-C로 노출시키는 MyModule-Swift.h 라는 헤더를 생성합니다. Swift 클래스를 사용하려면이 헤더를 가져옵니다.

// MySwiftClass.swift in MyApp
import Foundation

// The class must be `public` to be visible, unless this target also has a bridging header
public class MySwiftClass: NSObject {
    // ...
}
// MyViewController.m in MyApp

#import "MyViewController.h"
#import "MyApp-Swift.h"                    // import the generated interface
#import <MyFramework/MyFramework-Swift.h>  // or use angle brackets for a framework target

@implementation MyViewController
- (void)demo {
    [[MySwiftClass alloc] init];  // use the Swift class
}
@end

관련 빌드 설정 :

  • Objective-C 생성 된 인터페이스 헤더 이름 : 생성 된 Obj-C 헤더의 이름을 제어합니다.
  • Objective-C 호환성 헤더 설치 : -Swift.h 헤더가 공개 헤더 여야하는지 여부 (프레임 워크 대상).

빌드 설정 스크린 샷


다른 모듈에서

@import MyFramework; 사용 @import MyFramework; Obj-C 인터페이스를 포함한 전체 모듈을 Swift 클래스로 가져옵니다 (위에서 설명한 빌드 설정이 활성화 된 경우).

Swift 코드의 Objective-C 클래스 사용

MyFramework에 공용 헤더 (및 우산 머리글)에 Objective-C 클래스가 포함되어 있으면 Swift에서 import MyFramework 있으면됩니다.

브리징 헤더

브리징 헤더를 사용하면 Swift 코드에서 Objective-C 및 C 선언을 볼 수 있습니다. 프로젝트 파일을 추가 할 때 Xcode는 자동으로 브리징 헤더를 만들 수 있습니다.

브리지 헤더 대화 상자

수동으로 만들려면 Objective-C 브리징 헤더 빌드 설정을 수정하십시오.

여기에 이미지 설명을 입력하십시오.

브리징 헤더 내에서 코드에서 사용할 파일을 가져옵니다.

// MyApp-Bridging-Header.h
#import "MyClass.h"  // allows code in this module to use MyClass

생성 된 인터페이스

관련 항목 버튼을 클릭하거나 ^ 1을 누른 다음 생성 된 인터페이스 를 선택하여 Objective-C 헤더에서 생성되는 Swift 인터페이스를 확인합니다.

swiftc에 브리징 헤더 지정

-import-objc-header 플래그는 가져올 swiftc 의 헤더를 지정합니다.

// defs.h
struct Color {
    int red, green, blue;
};

#define MAX_VALUE 255
// demo.swift
extension Color: CustomStringConvertible {  // extension on a C struct
    public var description: String {
        return "Color(red: \(red), green: \(green), blue: \(blue))"
    }
}
print("MAX_VALUE is: \(MAX_VALUE)")  // C macro becomes a constant
let color = Color(red: 0xCA, green: 0xCA, blue: 0xD0)  // C struct initializer
print("The color is \(color)")
$ swiftc demo.swift -import-objc-header defs.h && ./demo
MAX_VALUE is: 255
The color is Color(red: 202, green: 202, blue: 208)

모듈 맵을 사용하여 C 헤더 가져 오기

모듈 맵 은 C 헤더 파일을 읽고 Swift 함수로 나타나도록 구성하여 import mymodule 을 간단히 import mymodule 수 있습니다.

mymodule 디렉토리에 module.modulemap 이라는 파일을 저장합니다.

디렉토리 구조

모듈 맵 파일 내부 :

// mymodule/module.modulemap
module mymodule {
    header "defs.h"
}

그런 다음 모듈을 import .

// demo.swift
import mymodule
print("Empty color: \(Color())")

swiftc 에게 모듈을 찾을 위치를 알려주 swiftc -I directory 플래그를 사용하십시오 :

swiftc -I . demo.swift   # "-I ." means "search for modules in the current directory"

모듈 맵 구문에 대한 자세한 내용은 모듈 맵에 대한 Clang 설명서를 참조하십시오.

Objective-C와 Swift 간의 세밀한 상호 운용

API가 NS_REFINED_FOR_SWIFT 로 표시되면 Swift로 가져올 때 접두어가 두 개의 밑줄 ( __ )로 표시됩니다.

@interface MyClass : NSObject
- (NSInteger)indexOfObject:(id)obj NS_REFINED_FOR_SWIFT;
@end

생성 된 인터페이스 는 다음과 같습니다.

public class MyClass : NSObject {
    public func __indexOfObject(obj: AnyObject) -> Int
}

이제 API 를 더 "Swifty"확장 프로그램으로 대체 할 수 있습니다. 이 경우 선택적 반환 값을 사용하여 NSNotFound를 필터링 할 수 있습니다.

extension MyClass {
    // Rather than returning NSNotFound if the object doesn't exist,
    // this "refined" API returns nil.
    func indexOfObject(obj: AnyObject) -> Int? {
        let idx = __indexOfObject(obj)
        if idx == NSNotFound { return nil }
        return idx
    }
}

// Swift code, using "if let" as it should be:
let myobj = MyClass()
if let idx = myobj.indexOfObject(something) {
    // do something with idx
}

대부분의 경우 Objective-C 함수에 대한 인수가 nil 이 될 수 있는지 여부를 제한하려고 할 수 있습니다. 이것은 포인터 또는 블록 참조를 규정하는 _Nonnull 키워드를 사용하여 수행됩니다.

void
doStuff(const void *const _Nonnull data, void (^_Nonnull completion)())
{
    // complex asynchronous code
}

작성된 것으로 컴파일러는 Swift 코드에서 해당 함수에 nil 을 전달하려고 시도 할 때마다 오류를 내 nil .

doStuff(
    nil,  // error: nil is not compatible with expected argument type 'UnsafeRawPointer'
    nil)  // error: nil is not compatible with expected argument type '() -> Void'

반대 _Nonnull 있다 _Nullable 그것을 통과하는 것을 허용되는 의미 nil 이 인수. _Nullable 도 기본값입니다. 그러나이를 명시 적으로 지정하면 더 많은 자체 문서화되고 미래 보장적인 코드가 허용됩니다.

코드를 최적화하여 컴파일러를보다 잘 돕기 위해 블록이 이스케이프 처리 중인지 여부를 지정할 수도 있습니다.

void
callNow(__attribute__((noescape)) void (^_Nonnull f)())
{
    // f is not stored anywhere
}

이 속성을 사용하여 블록 참조를 저장하지 않고 함수 실행이 완료된 후에 블록을 호출하지 않을 것을 약속합니다.

C 표준 라이브러리 사용

Swift의 C 상호 운용성을 통해 C 표준 라이브러리의 함수와 유형을 사용할 수 있습니다.

Linux에서 C 표준 라이브러리는 Glibc 모듈을 통해 공개됩니다. 애플 플랫폼에서는 Darwin 이라고 불린다.

#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
import Darwin
#elseif os(Linux)
import Glibc
#endif

// use open(), read(), and other libc features


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow