サーチ…


備考

詳細については、AppleのココアとObjective-CでのSwiftの使用に関するドキュメントを参照してください。

Objective-CコードのSwiftクラスの使用

同じモジュール内で

" MyModule "という名前のモジュールの中で、Xcodeは、Public 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 Generated Interface Header Name :生成されたObj-Cヘッダーの名前を制御します。
  • Objective-C互換性ヘッダーのインストール :-Swift.hヘッダーをパブリックヘッダー(フレームワークターゲット用)にする必要があるかどうか。

ビルド設定のスクリーンショット


別のモジュール

@import MyFramework;を使用する@import MyFramework; Obj-Cインターフェイスを含むモジュール全体をSwiftクラスにインポートします(前述のビルド設定が有効な場合)。

SwiftコードのObjective-Cクラスの使用

MyFrameworkにObjective-Cクラスがパブリックヘッダ(および傘のヘッダ)に含まれている場合、MyFrameworkをimport MyFrameworkするだけでSwiftからそれらを使用する必要があります。

ブリッジヘッダー

ブリッジヘッダーは、Swiftコードに追加のObjective-CおよびC宣言を表示します。プロジェクトファイルを追加するとき、Xcodeは自動的にブリッジヘッダーを作成することができます:

ブリッジヘッダーダイアログ

手動で作成するには、 Objective-C Bridging Headerビルド設定を変更します。

ここに画像の説明を入力

ブリッジヘッダー内で、コードから使用する必要があるファイルをインポートします。

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

生成されたインタフェース

関連項目ボタンをクリックするか(または^ 1を押す)、 Generated Interfaceを選択して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することができます。

名前のファイルに置きmodule.modulemapという名前のディレクトリ内mymodule

ディレクトリ構造

モジュールマップファイルの内部:

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

次に、モジュールをimportします。

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

モジュールを見つける場所を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にインポートすると、接頭辞には2つのアンダースコア( __ )が付きます:

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

生成されるインタフェースは次のようになります。

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

これで、APIをよりスウィーティーな拡張機能に置き換えることができます。この場合、 オプションの戻り値を使用して、 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を渡そうとするたびにエラーを出力します:

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

_Nonnullの反対は_Nonnullです。 _Nullable 、この引数にnilを渡すことは許容されます。 _Nullableもデフォルトです。しかし、それを明示的に指定することにより、より多くの自己文書化された将来的なコードが可能になります。

コンパイラがコードを最適化するのをさらに助けるために、ブロックがエスケープしているかどうかを指定することもできます。

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

この属性では、ブロック参照を保存しないで、関数の実行が終了した後にブロックを呼び出さないことを約束します。

C標準ライブラリを使用する

SwiftのC相互運用性により、C標準ライブラリの関数と型を使用できます。

Linuxでは、C標準ライブラリはGlibcモジュールを介して公開されています。 Appleプラットフォーム上ではDarwinと呼ばれて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