Xcodeでは、フレームワークを「必須」ではなく「オプション」に設定できます。これは、フレームワークが弱くリンクされていることを意味します。
フレームワークは、どこかにインポートされたときにのみバンドルに含まれるという意味ですか?
プライベートAPIを使用するいくつかのデバッグフレームワークを弱くリンクしたいのですが、それらをAppStoreビルドに表示したくありません。
重要な注意:この回答はiOS8が発表される前に書かれました。技術的な詳細は引き続きシステムフレームワークに適用されますが、アプリバンドル内で出荷される独自の動的にリンクされたフレームワークを構築できるようになりました。制限があります。たとえば、アプリとその拡張機能のみが埋め込みフレームワークの同じインスタンスにリンクできますが、iOS 8以降、カスタムの動的にリンクされたフレームワークが可能であるという事実は変わりません。 。詳細については、 このガイド (組み込みフレームワークを使用したコードの共有)およびWWDC 2014セッション416最新のフレームワークの構築。
元の回答:(プラットフォーム)フレームワークのどれも実際には「バンドルに含まれていません」。代わりに、「バイナリとライブラリのリンク」ビルドフェーズに追加すると、アプリにはフレームワークへの参照( "link")があります。フレームワークはデバイスにプリインストールされています。アプリを実行すると、アプリのすべてのフレームワーク参照が(デバイス上の)ダイナミックリンカーによって解決されます。つまり、アプリが使用できるようにフレームワークコードが読み込まれます。
一部のフレームワークは、サポートする予定のすべてのデバイスで使用できない場合があります。たとえば、PassKitはiOS 6で導入されました。iOS5デバイスでPassKitに対してリンクするアプリを実行すると、動的リンカーができないため、起動直後にクラッシュします。デバイス上のフレームワークを見つけます。ただし、PassKitをウィークリンクすると、フレームワークが見つからなかった場合、ダイナミックリンカーはすべてのフレームワークのシンボルをnil
に設定します。これにより、アプリがクラッシュするのを防ぎ、実行時にシンボルの可用性を確認できます。例:
if ([PKPass class]) {
// Class is available - use it
PKPass *pass = [[PKPass alloc] init];
}
[PKPass class]
はすべてのデバイス/システムで安全に使用できます。古いシステムではPKPass
クラスシンボルがnil
になり、Objectiveではメッセージングnil
は問題にならないためです。 -C。
ウィークリンクの詳細: Appleドキュメント
あなたの質問に本当に答えるには:
それは、フレームワークがどこかにインポートされたときにのみバンドルに含まれることを意味しますか?
いいえ。フレームワークは常にアプリからリンクされます。アプリが実行されている実際のデバイスでフレームワークが見つからない場合にのみ、フレームワークはロードされません。
1つの解決策は、デバッグビルドとAppStoreビルドに別々のターゲットを設定することです。別の方法は、Xcodeの組み込みの「バイナリとライブラリのリンク」ビルドフェーズを使用せず、リンカーオプションを介してデバッグフレームワークをリンクすることです。これらは、次のように、構成(Debug/Release/...)ごとに個別に指定できます。
弱くリンクしたい場合は、代わりに-weak_framework PassKit
(もちろん、PassKitはここでの単なる例です...フレームワークの名前を挿入してください)を使用してください。デバッグフレームワークがデフォルトのフレームワークディレクトリの1つにない場合は、フルパスを指定するか、フレームワークの検索パスを変更する必要があります。さらに、おそらくマクロを使用して、デバッグフレームワークを使用するコードがAppStoreビルドに到達しないようにする必要があります。
編集:Xcode 5以降のもう1つのオプションは、@import <FrameworkName>;
を使用することです。このようにして、「Link Binary ...」フェーズを空のままにして、コード内のフレームワークのリンクをトリガーできます。次に、DEBUG
などのマクロを使用して、一部のフレームワークがAppStoreのビルドに使用されていないことを確認できます。 @import
に関して 優れた回答 があります。
IAdsを使用しているときに弱いリンクに遭遇しました。問題は、iAdsフレームワークを強力にリンクし、iAdsをサポートしていないSDKを備えたデバイスでアプリを実行すると、単にクラッシュすることでした。クラッシュを回避するために許可された弱いリンク。リンクが弱い場合でも、フレームワークが利用可能かどうかをコードでチェックインする必要があると私は信じています。
それは、フレームワークがどこかにインポートされたときにのみバンドルに含まれることを意味しますか?
これは、スキームまたはターゲットをどのように構成したかによって異なります。
1つのスキームをデバッグにのみ使用し、オプションのフレームワークをそこにのみ含めることができます。リリース用のオプションのフレームワークなしで別のスキームを使用します。
[〜#〜]更新[〜#〜]
これを行うには、プロジェクト構成に基づいて新しいスキームを作成し、 hagiの回答 の説明に従ってOTHER_LDFLAGS
を設定します。