いつのまにか、iOSでdynamic libraryaが使えるようになったんですね。最近まで知りませんでした・・・
最近になって、Chocolate SweeperでIn App Purchaseが失敗する不具合に気付いて、調べてみると、どうもOpen SSLの関数がエラーを返しているみたい。で、色々試してみた結果、Google Play Service for iOSに含まれている(と思われる)Open SSLのライブラリのバージョンがアプリで使っているやつと違っていて、Google Play Serviceの方がリンクされてしまっていたのが原因のようでした。
Google Play Serviceを外せばうまく行くんだけど、そうするとセーブデータのバックアップとか機種変更のサポートができなくなっちゃうので、なんとかしようということで、dynamic libraryを使うことにしました。つまり、Google Play Serviceのライブラリをdynamic libraryの中に閉じ込めて、アプリには直接リンクさせない作戦です。
しかし、いざ使ってみると、「dyld: Library not loaded」というエラーがでてアプリの起動に失敗してしまいます。たぶん、これはみんなひっかかるんじゃないでしょうか。で、Googleで調べてみると、対処方法が出てくるんですが、微妙に自分の環境と違ったのでメモを残しておきます。
エラーの原因は明確で、dynamic libraryが実行時にみつからなかったから。そのため、
- dynamic libraryをアプリのパッケージに含めて
- dynamic libraryを探すパスにパッケージ内のパスを追加する
必要があるのです。
まず 1 の方ですが、プロジェクトのBuild PhasesにCopy Filesを追加して、そこでdynamic libraryをコピーするようにします。
2の方はBuild SettingsのRunpath Search Pathsに「@executable_path/Frameworks」を追加します。
Googleで検索すると「@executable_path/../Frameworks」を追加するというのがみつかるんですが、iOSのアプリの場合、dynamic libraryはアプリのパッケージに含まれるので、親のディレクトリに戻らずに、パッケージ内のFrameworksディレクトリを指定しないといけないみたいです。MacやPCだったらdynamic librarlyを他のアプリと共有するためにディレクトリをひとつ戻るというのは納得なんですけどね。