【Unity + AdMob + CocoaPods + iOS】エラーなくビルドを通すための最適解【Androidにも応用できる】

こんにちは！
ねこじょーかー（[@nekojoker1234](https://twitter.com/nekojoker1234)）と申します。

みなさんは、UnityEditor 上だけでなく、実機で動作確認したことはありますか？

**実機で動作確認をするには「ビルド」が必要になるのですが、これがまた本当にやっかいです。**
何がやっかいなのかと言うと、とにかくエラーが出ることが多く、そしてそのエラー解決も一筋縄ではいきません。

私が遭遇したやっかいなエラーたちは以下の通り。

- GoogleMobileAds/GoogleMobileAds.h' file not found
- Undefined symbols for architecture arm64
- Undefined symbols for architecture armv7
- linker command failed with exit code 1

エラー内容で調べるといろいろと情報は出てくるのですが、Unity のバージョンが新しいせいか、どれも解決にはいたりませんでした。

> - [Unity Cloud BuildでiOSビルド時にCocoaPodsを利用する（ワイルドカード証明書利用）](http://alice3.net/unity/post-4068)
> - [【Unity、iOS】AdMob入れたらModule 'GoogleMobileAds' not found.が消せなくて困った。](https://blog.naichilab.com/entry/admob-framework-not-found)
> - [Automating Unity iOS builds](http://educoelho.com/unity/2015/06/15/automating-unity-builds-with-cocoapods/)

もうダメかな...と諦めかけていたとき、ついに解決方法を見つけ、無事にエラーなくビルドすることができるようになりました。

私は解決に数日間かかりハゲそうになったので、他の人がハゲてしまわないよう、この記事に残しておきます。

ということで、さっそく見ていきましょう。

## エラーなくビルドを通すための最適解

### External Dependency Manager for Unity のインポート

まずは、[External Dependency Manager for Unity](https://github.com/googlesamples/unity-jar-resolver)をダウンロードしてください。

**これが今回の肝となるプラグインで、簡単な記述をするだけで、iOS や Android でやっかいな依存関係のエラーを解決してくれるという優れものです。**

Google が出しているプラグインなので、安心ですね。

この中にある、`external-dependency-manager-latest.unitypackage`をインポートしていきます。

<img width="365" alt="スクリーンショット 2020-04-26 16.23.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487218/2e967515-9660-40d0-4ce3-17ad066ea9a8.png">

こんな画面が出てくるので、そのままインポートしましょう。

<img width="578" alt="スクリーンショット 2020-04-26 16.29.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487218/1419a20d-f274-b7dc-3ede-735e40849b87.png">

[Google Mobile Ads Unity Plugin](https://github.com/googleads/googleads-mobile-plugins/releases/latest) をすでに入れている場合は、一部更新マークになります。

すると、インポート中にできたゴミファイルを削除していいか聞かれるので、Apply で削除しておきましょう。

<img width="629" alt="スクリーンショット 2020-04-26 16.32.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487218/cfcf0f33-3984-51d1-d545-73f4f8714ab0.png">

ここから少し時間が経つと、統計情報の取得をしてもいいか聞かれます。

<img width="576" alt="スクリーンショット 2020-04-26 16.35.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487218/8068894e-a27e-d493-1ec0-ffe5633cb494.png">

どちらでもいいですが、私は No を選択しました。

あと2画面出てくるのですが、両方とも右下のボタンを押せばOKです。

「Add Selected Registries」を選択

<img width="1136" alt="スクリーンショット 2020-04-26 16.38.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487218/0bfffab6-faba-2198-29af-c67fab09367b.png">

「Apply」を選択

<img width="1136" alt="スクリーンショット 2020-04-26 16.39.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487218/5a2771fd-6623-9b27-c8cd-7ae5385e7870.png">

これでインポートは完了です。

### Dependencies.xml の準備

続いて、[SampleDependencies.xml](https://github.com/googlesamples/unity-jar-resolver/blob/master/sample/Assets/ExternalDependencyManager/Editor/SampleDependencies.xml) をダウンロードしてきます。

これをプロジェクトのフォルダに置くのですが、2つルールがあるので注意してください。

- `MyPlugin/Editor`の直下に置く
- Editor の上位階層のフォルダ名と、Dependencies の前につけた文字列を一致させる。（今回の例だと`MyPluginDependencies.xml`）

たとえば、上位階層のフォルダが「DownhillRush」だとすると、以下の構造になっていればOKです。

<img width="328" alt="スクリーンショット 2020-04-26 17.10.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487218/e8ef59d7-2c79-0abc-0419-2c5a55e4277f.png">

次に、XML ファイルの中身を修正していきます。

ファイルの一番下を見ると、以下の記載があります。

```xml
<iosPod name="Google-Mobile-Ads-SDK" path="../google-mobile-ads-sdk" version="~> 7.0" bitcodeEnabled="true"
        minTargetSdk="6.0">
  <!-- Set of source URIs to search for this Cocoapod spec.
       By default Cocoapods will attempt to fetch the pod specs from:
       * $HOME/.cocoapods/repos
       * https://github.com/CocoaPods/Specs
       -->
  <sources>
    <source>https://github.com/CocoaPods/Specs</source>
  </sources>
</iosPod>
```

今回は、`Google-Mobile-Ads-SDK`だけあればいいので、ここを少し修正します。

```xml
<iosPod name="Google-Mobile-Ads-SDK" version="~> 7.0" bitcodeEnabled="false" minTargetSdk="6.0">
```

`bitcodeEnabled`は色んなサイトで「false にしとけ」と書かれていたので、とりあえず false にしておきます。
`path`はローカルの CocoaPod のパスらしいのですが、よくわからないので消しました。

また、ビルド時に「cocoapods.mycompany.com/Specs が見つからない」とエラーになるので、以下の`sources`タグはコメントアウトしておきましょう。

修正前

```xml
<!-- Global set of sources to search for Cocoapods.
     These sources will be searched for all Cocoapods specified by
     iosPod. -->
<sources>
  <source>https://cocoapods.mycompany.com/Specs</source>
</sources>
```

修正後

```xml
<!-- Global set of sources to search for Cocoapods.
     These sources will be searched for all Cocoapods specified by
     iosPod. -->
<!--<sources>
  <source>https://cocoapods.mycompany.com/Specs</source>
</sources>-->
```

これで XML の準備は完了です。

### iOS Resolver の設定変更

`Assets > External Dependency Manager > iOS Resolver > Settings` を開きます。

<img width="902" alt="スクリーンショット 2020-04-26 16.59.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487218/c5f0f006-1c79-1871-a244-2fd24a87dd3d.png">

Cocoapods Integration を、`Xcode Project - Add Cocoapods to the Xcode project`に変更します。

<img width="512" alt="スクリーンショット 2020-04-26 17.02.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487218/75ce8305-a63b-3611-1f84-8d5054713a95.png">

xcworkspace のファイルを作らずに、Xcode のプロジェクトファイルの中に CocoaPods の設定を含めるようにする、という変更です。

これですべての準備が整いました。

### ビルド

あとはビルドをすれば、エラーなくビルドができるはずです。

私はこの方法にたどり着くまでに、35回もビルドを失敗してしまいました...

<img width="378" alt="スクリーンショット 2020-04-26 13.18.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487218/a0e6576b-b799-784b-0c3f-98d59891c77c.png">

今回は iOS で試しましたが、Android でも専用の手順の通りやることで、ビルドが通るようになると思います。

みなさんがこの記事を参考に、一発でビルドが通れば嬉しいです。

### おまけ

PlayFab に関するブログも書いているので、よければ合わせてご覧ください。
https://playfab-master.com/