選択肢 2.論外 (詳細は後述)
選択肢 3. おっしゃる通り、本当に避けるべきです。
オプション 1が最適です。Obj-C と Swift を念頭に置いて API を設計するだけです。どういう意味ですか ?
• セレクターを使用しないでください。セレクターは Swift の標準ではありません。
• null 可能性を使用してオプションに変換する
• クロージャとブロックは同じ構文を持つ場合がありますが、わずかな違いがあります。注意してください。
Swift クロージャーと Objective-C ブロックは互換性があるため、Swift クロージャーを、ブロックを予期する Objective-C メソッドに渡すことができます。Swift のクロージャーと関数は同じ型なので、Swift 関数の名前を渡すこともできます。
クロージャーはブロックと同様のキャプチャ セマンティクスを持ちますが、1 つの重要な点で異なります。変数はコピーではなく変更可能です。つまり、Objective-C の __block の動作は、Swift の変数のデフォルトの動作です。
出典: Apple のUsing Swift with Cocoa and Objective-C - すべてが詳細に説明されています。
詳しくはこちらをご覧ください。
そのような API を設計するときは、すべてがどのように変換されるかを知る必要がありますが、それを正しく行えば、ユーザーは違いに気付かないでしょう :)
モジュールファイル
フォルダとファイルが入った状態x.framework
で出荷されていることを確認してください。modules
新しい Xcode がそれを生成します。このようにして、ユーザーは Obj-C プロジェクトをブリッジング ファイルに追加せずに Swift で使用できます。そのため、箱から出してすぐに使用できimport myLib
ます。

なぜSwiftではないのですか?
残念ながら、コンパイル済みライブラリを現時点で配布する最も賢明な方法は、それを Objective-C で記述することです。
それは 1 つの大きな理由によるものです: Swift Binary Compatiblity Problem
アプリのランタイム互換性が保証されている間、Swift 言語自体は進化し続け、バイナリ インターフェイスも変更されます。安全のために、アプリのすべてのコンポーネントを同じバージョンの Xcode と Swift コンパイラでビルドして、それらが確実に連携するようにする必要があります。
これは、フレームワークを慎重に管理する必要があることを意味します。たとえば、プロジェクトでフレームワークを使用して埋め込み拡張機能とコードを共有する場合、フレームワーク、アプリ、および拡張機能を一緒にビルドする必要があります。Swift を使用するバイナリ フレームワーク (特にサード パーティ製) に依存するのは危険です。Swift が変更されると、これらのフレームワークはアプリの残りの部分と互換性がなくなります。バイナリ インターフェイスが 1 ~ 2 年で安定すると、Swift ランタイムがホスト OS の一部になり、この制限はなくなります。
コンパイル済みライブラリとして配布されているライブラリでもある PSPDFKit の創設者である Peter Steinberger は、同じ問題に遭遇しました。