Objective-CコードはClassでSwift拡張を呼び出すことができますか?


94

いくつかの投稿を検索しましたが、swiftで拡張機能を記述できず、Objective-Cコードから呼び出すことはできないと思います。

@objcのような属性は、メソッド、クラス、プロトコルのみをサポートしますか?


1
試してみませんか?
2014年

7
ideはエラーを訴えましたが、明確なanwserを取得したいと思います。
sprhawk 2014年

回答:


84

Swift拡張機能を記述して、Objective-Cコードで使用できます。XCode 6.1.1でテスト済み。

あなたがする必要があるのは:

  • Swiftで拡張機能を作成(@objc注釈なし)

  • #import "ProjectTarget-Swift.h" Objective-Cクラス内(「ProjectTarget」はSwift拡張機能が関連付けられているXCodeターゲットを表します)

  • Swift拡張機能からメソッドを呼び出す

更新: @Rizwan Ahmedについては、@objcアノテーションを追加する必要があります。

Swift 4.0.3以降、Objective Cクラスファイルで拡張機能を使用する場合、@ objcアノテーションが必要です。


6
私はこれを正確に行いましたが、それでもコンパイル時エラーです。うーん。編集:「ProjectTarget-Swift.h」の代わりにブリッジヘッダーをインポートしました。デア
Jason Renaldo 2015年

どちらもブリッジヘッダーです。違いは、1つはObjCでSwiftコードを使用するためのものであり、もう1つはSwiftでObjCコードを使用するためのものです。Swiftヘッダーは非表示です。もう1つは、あなたが管理する必要があります。
marius bardan 2015年

ウィリアム・フー、マクラフリンジの答えを見てください!
appleitung 2016

39
Swift 4.0.3以降、Objective Cクラスファイルで拡張機能を使用する場合、@ objcアノテーションが必要です。
リズワンアーメド2017

68

私は中にいることが分かったスウィフト4.0私は追加する必要がありました@objc、私の目の前で、拡張 Iは、拡張されたにObjCクラスのインスタンスで見えるようになるためにスウィフトの拡張メソッドのための順序でキーワード。

要するに:

ファイル構成のセットアップ:

CustomClass.h
CustomClass.m
CustomClassExtension.swift

CustomClassExtension内:

@objc extension CustomClass
{
    func method1() 
    {
        ...
    }
}

私のAppDelegate.mで:

self.customClass = [[CustomClass alloc] init];
[self.customClass method1];

2
メソッドがジェネリックスを使用する場合、Objective-Cでは使用できず、@nonobjcアノテーションを追加する必要があります。
ThomasW 2018年

余談ですが、この場合@objcMembersは機能しません。理由がわからない.. :-(
Raunak '22

46

このソリューションは、Swift 2.2およびSwift 3で機能します。Objective-Cからアクセスできるのは、クラスの拡張(構造体や列挙型ではない)だけであることに注意してください。

import UIKit

extension UIColor {

    //Custom colours
    class func otherEventColor() -> UIColor {
        return UIColor(red:0.525, green:0.49, blue:0.929, alpha:1)
    }
}

次に、ObjCファイルに#import "ProductModuleName-Swift.h"追加します。

スウィフト4

extension UIColor {

    // As of Swift 4.0.3, the @objc annotation is needed if you want to use the extension in Objective-C files
    @objc
    class func otherEventColor() -> UIColor {
        return UIColor(red:0.525, green:0.49, blue:0.929, alpha:1)
    }
}

それは「... YourTargetsNameHere」「... YourProjectsNameHere」ではないですが、むしろ:共有ターゲットに、あなたは名前にそれをロックする必要があります。 dr2050.postach.io/post/...
ダンRosenstark

1
@DanRosenstarkあなたは正しいです。:アップルが示唆するように、私は「ProductModuleName-Swift.h」に変更するのですdeveloper.apple.com/library/ios/documentation/Swift/Conceptual/...
FOTI薄暗い

1
罰金は、SWIFT 3.のための作品集
ヴィクトルクセラ

あなたpublicが必要だと言う理由はありますか?public私のために修飾子なしでうまくいきます。拡張機能が同じプロジェクトにないが、別のプロジェクトからインポートされていると想定していますか?
Lee Kang

ブリッジヘッダーを使用する必要がありますか?
jegadeesh 2017

42

他の回答で説明されているように、生成されたSwiftヘッダーのインポートはほとんどの場合に機能します。

これの例外は、カテゴリーがブリッジタイプで定義されている場合です(つまり、拡張子がで定義されString、で定義されていない場合NSString)。これらのカテゴリは、Objective-Cの対応するカテゴリに自動的にブリッジされません。これを回避するには、Objective-Cタイプを使用する(そして、Swiftコードでを使用して戻り値をキャストするas String)か、SwiftタイプとObjective-Cタイプの両方の拡張を定義する必要があります。


2
上記の答えに加えて、迅速な拡張を公開し、そのタイプをNSStringとして設定する必要がありますpublic extension NSString。コンパイル時に未解決の識別子または同様のエラーが発生した場合は、たとえばStringに再度キャストしてlet sVal = self as String、必要なコードを呼び出すsVal
RunLoop

@RunLoopは実際にはパブリックである必要はありません。スコープ指定子なしで動作します。そして、それは(Obj-Cへのエクスポート、つまり)文字列に対しては機能しません。なぜなら、それらはクラスではなく構造体であり、Swiftからしか利用できないためです。したがって、はい– NSStringの拡張を記述してキャストを使用するか、またはmclaughlinjNSStringクラスとString構造体の両方に拡張を書き込むことができます
Alex Nazarsky

3

インポート 「の#import 『ProductModuleName-Swift.h』 Objective-Cのファイルのヘッダーおよび追加@objcあなたのインフロントextentsionを迅速ファイルに。それは迅速4.2かつ迅速に正常に動作します5

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.