kitoko552.memo

kitoko552のメモ

EMBEDDED CONTENT CONTAINS SWIFT CODEの正体を暴く

要点

  • EMBEDDED CONTENT CONTAINS SWIFT CODEは、Swiftの標準ライブラリをアプリバンドルにコピーするかどうかを決める値
  • YESにすると、Swiftの標準ライブラリがアプリバンドルにコピーされる。
  • Swiftを使っているプロジェクトでは、これをYESにしようがNOにしようが関係ない。
  • 以下参考URL

developer.apple.com

developer.apple.com

stackoverflow.com

CocoaPodsでの警告

あるとき、新しいライブラリをプロジェクトに取り込んでpod installをすると、以下の警告が出ました。

[!] The `$(Target) [$(Contribution)]` target overrides the `EMBEDDED_CONTENT_CONTAINS_SWIFT` build setting defined in `Pods/Target Support Files/Pods/Pods.$(Contribution).xcconfig'. This can lead to problems with the CocoaPods installation
    - Use the `$(inherited)` flag, or
    - Remove the build settings from the target.

簡潔に訳すと、「xcconfigで指定しているEMBEDDED_CONTENT_CONTAINS_SWIFTの値と、$(Target) [$(Contribution)]のBuild Settingsで設定している値が違うのでオーバーライドしちゃいますよ。」ってことです。

ではそれぞれ見てみましょう。

まずはxcconfig。

f:id:kitoko552:20160118210549p:plain

そしてBuild Settings。

f:id:kitoko552:20160118205518p:plain

ご覧のように、xcconfigの設定がYESで、Build Settingsでの設定がNOでした。

Build Settingsの値が最終的に採用される

こういった場合、xcconfigで設定された値をBuild Settingsで設定した値がオーバーライドしてしまいます。

つまり、最終的に採用される値は、NOになるということです。

XcodeのBuild Settingsで"Levels"にして見てみると一目瞭然です。

f:id:kitoko552:20160118210208p:plain

xcconfigではYESですが、最終的にはNOになっています。

CocoaPodsの警告はこのことを言っているのです。

EMBEDDED CONTENT CONTAINS SWIFT CODEってなに?

解決策としては、Build SettingsでのEMBEDDED CONTENT CONTAINS SWIFT CODEをYESにしてやれば警告は消えます。

f:id:kitoko552:20160118205412p:plain

しかし、EMBEDDED CONTENT CONTAINS SWIFT CODEという値が何を表しているのかを知らずにYESに設定してしまうのは危険です。

結論から言うと、EMBEDDED CONTENT CONTAINS SWIFT CODEは、Swiftの標準ライブラリをアプリバンドルにコピーするかどうかを決める値です。

つまり、これをYESにするとSwiftの標準ライブラリがアプリバンドルにコピーされます。

そもそもこの値は、Objective-Cのみで構成されているプロジェクトがSwiftで構成されている外部のライブラリ等を使う際に、Swiftの標準ライブラリをアプリバンドルにコピーする必要があるため作られた値です。

そのため、プロジェクトがSwiftで構成されているもの、もしくはSwiftとObjective-C両方で構成されているものに関しては、YESにしてもNOにしてもどちらでもいいということになります。

なぜなら、Swiftを少しでも使っているプロジェクトは何もしなくてもSwiftの標準ライブラリがアプリバンドルに入るはずだからです。

コピーされようがされまいが同じことですね。

重複コピーはされないのか

しかし、ここでSwiftの標準ライブラリが重複してコピーされてしまうのではないかという疑問が出てきます。

実際に、Swiftで構成されているプロジェクトで、EMBEDDED CONTENT CONTAINS SWIFT CODEをYESにしたときと、NOにしたときとでアプリのサイズを比較してみたところ、サイズは変わりませんでした。

これは、Swiftの標準ライブラリが重複してコピーされていないことを表します。

したがって、Swiftを使っているプロジェクトでは、EMBEDDED CONTENT CONTAINS SWIFT CODEをYESにしようがNOにしようが関係ないのです。

CocoaPodsはなぜEMBEDDED CONTENT CONTAINS SWIFT CODEをYESに設定するのか

これは僕の予測ですが、CocoaPodsはObjective-Cのみ使っているプロジェクトのことを考えてこの値をYESにしているのだと思います。

なぜなら、Objective-Cのみ使っているプロジェクトがSwiftのライブラリをCocoaPods経由でインストールしている場合、EMBEDDED CONTENT CONTAINS SWIFT CODEがYESになっていないといけないからです。

そして、Swiftを使っているプロジェクトはどちらの値を設定しても何も変わらないということを知っているため、YESに設定しないと困るObjective-Cのみ使っているプロジェクトのことを考えてYESにしているのではないでしょうか。