【ReactNative】実機ビルド、テストアプリビルド(Archive)で起きたトラブルシューティング～IOS編～

こんにちは。ブリューアスwebフロントエンジニアのsuginokoです。
前回、[実機ビルド、APK生成で起きたトラブルシューティング～Android編～](https://qiita.com/suginoko/items/cdae27d68a08decddc8c)
書かせていただきましたがこちらのIOS編です。

今回も初めてのReactNativeで出くわしたトラブルシューティングを書いていこうと思います。
前回と同じことを書きますが、アプリ開発に携わったことのない同じようなフロントエンジニアさんに届きますように～
(ios色々苦戦して弊社のエンジニアに聞きまくりました。ありがとうございます。優しい世界。)


## 環境
* react: 16.9.0
* react-native: 0.61.5
* react-native-agora: 2.9.1-alpha.2
* react-native-firebase: 5.6.0

※XCode12
※パッケージはおおまかに使用したものだけ記載
基本的にはwindowsで実装してますが、expoは使用しておらず、ios開発は別途Macを用意して確認しつつの実装を行ってました。
yarnも使ってます。

お客様の環境が開発用と本番用としか分かれてなかったため、buildTypeとしては

* Debug(開発環境)
* Staging(開発環境を参照しているデプロイゲート更新用)
* Release(本番)

参考：https://qiita.com/Todate/items/a2e6a26731c79bd23e02
(自分は今回ここまでやってないけど。今後の参考に。)

このように分けました。
今回の納期までのスケジュールではもろもろのパッケージのバージョンアップは行わない方針でいったので後に書きますトラブルに見舞われた可能性があります。。

## トラブルシューティング

### Can’t find ‘node’ binary to build React Native bundle
XCodeでの実機ビルドで起きたエラーです。
参考：[React Native エラー　Can’t find ‘node’ binary to build React Native bundle - Qiita](https://qiita.com/YutamaKotaro/items/00749491cb1d5f7b82ba)
node をnodebrewで管理している場合は上記が使える
こちらに書いていることですが、参照しているnodeの場所を変更することでエラーが消えます。

Xcode
Project　＞　TARGETS > APP Name > Build Phases > Bundel React Native code and image

```
export NODE_BINARY=$HOME/.nodebrew/current/bin/node
../node_modules/react-native/packager/react-native-xcode.sh
```

### Failed to create provisioning profile. No profiles for 'XXXXXXXX.APName' were found
こちらもXcodeのエラーです
このパターンは色々ありました。見直してみましょう。

* ちゃんとAppleのDeveloperサイトに自分のアカウントが登録されてなかった
    * AppleID作って登録しましょう。(初歩)

* 開発用の実機が登録されてなかった
    * 実機ビルドに必須です。登録しましょう。
        * https://developer.apple.com/account/resources/devices/list

* provisioning Profile (構成ファイルのこと)が登録されてなかった
    * 証明書の登録
        * https://developer.apple.com/account/resources/certificates/list
    * Identifiersの登録
        * https://developer.apple.com/account/resources/identifiers/list
    * Profilesの登録
        * https://developer.apple.com/account/resources/profiles/list
    * [証明書参考まとめ](https://shigu493.com/%E3%80%90ios%E3%80%91%E8%A4%87%E9%9B%91%E3%81%AA%E8%A8%BC%E6%98%8E%E6%9B%B8%E5%91%A8%E3%82%8A%E3%82%92%E3%81%82%E3%81%A3%E3%81%95%E3%82%8A%E6%95%B4%E7%90%86/)
    * [証明書参考まとめ2](https://mbaas.nifcloud.com/doc/current/tutorial/push_setup_ios.html)

参考：https://qiita.com/Gokna/items/9185d4bf8260b3bff4c1

Profileや証明書は登録をしてもまだエラーが出る場合はXcodeを再起動してみましょう。それで直るパターンがありました。

### ビルド時{appname}Testsのせいでbuildができなくなる
開発版で実機buildの際おそらくreact-native initで作られるテスト用のソースが書いているものがあるのですが、それでエラーが起きる場合があります。
{appname}Testsをテストで使用しているのであればともかく、使ってなければ以下で解消しました。

```
{appname}Testsの${appname}Tests.mというファイルでテストされているものをコメントアウトする
TestsをTARGETにしてgenenal Testing をNoneにする
TestsのSigning & CapabilitiesのAutomatically manage signingにチェックして会社の端末アカウントに。
```
スキームも確認しましょう。間違ってTestsになっている場合はTargetが間違っている場合もあります。


```
TARGETS　アプリ名(一番上)
Build settingタブ⇒signingのチームを適したものに直す。
```

### Failed to register bundle identifier.
XCodeで起きたエラーです
bundle identifierの名前がどうもダメ見たいです。
環境ごとに名称を変えてあげないとエラーになるっぽいので、

TARGETS　⇒　アプリ名
`Signing&Capabilities` の　`bundle identifier` をそれぞれの環境ごとに設定します。

* Debug(開発環境)　⇒　com.アプリ名-dev
* Staging(開発環境を参照しているデプロイゲート更新用)　⇒　com.アプリ名-stg
* Release(本番)　⇒　com.アプリ名

### the plist file at path .xcodeproj/project.pbxproj doesn't exist
単に.xcodeproj/project.pbxprojがなかったので
もらったプロジェクトに入ってたんで拾ってきて入れました。

### Terminating app due to uncaught exception 'com.firebase.core', reason: '`[FIRApp configure];` (`FirebaseApp.configure()` in Swift) could not find a valid GoogleService-Info.plist in your project. Please
向けているアプリのターゲットが
`{アプリ名}App-tvOS`になっていたので`{アプリ名}`することで解決しました。
(左上にデバイス選択できるところ)

普通は変わらないのに何かの拍子に変わってしまったのでしょう・・・気を付けよう・・

### cp: “/プロジェクト名/ios/Config/Debug/GoogleService-Info.plist”: No such file or directory Command PhaseScriptExecution failed with a nonzero exit code

と

### error: Build input file cannot be found: 'プロジェクト名/ios/GoogleService-Info.plist' (in target 'SmileFarmApp' from project 'SmileFarmApp')

Xcodeにて、iosでBuildやArchiveしたいときに、環境ごとに読み込むenvファイルをみて処理を変えてほしい処理を書いたときに起きたエラーです。
envファイルを見つつ、firebaseで使用するGoogleService-Info.plistのファイルも変えてほしかった、というところです。

前提として、firebase側は
Firebase上のプロジェクトにアプリをConfiguration分(Debug,Stating,Release)分けています。登録済み。

参考：https://qiita.com/KazaKago/items/aacf6eaec65b6d4244d0

TARGETS ⇒　Build Phase
+ボタンを押して読み込むGoogleService-Info.plistを分岐するための名称を付けてシェルを書いていきます
firebaseのバージョンがv5だからなのか結構苦戦しました。

v6(だからなのかわからなかったけど)だと

```
cp “${PROJECT_DIR}/Configs/${CONFIGURATION}/GoogleService-Info.plist” “${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist”
```

v5だと

```
if [ "${CONFIGURATION}" = "Debug" ]; then
  cp "${PROJECT_DIR}/Configs/${CONFIGURATION}/GoogleService-Info.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
  echo "Debug GoogleService-Info copied."
elif [ "${CONFIGURATION}" = "Staging" ]; then
  cp "${PROJECT_DIR}/Configs/${CONFIGURATION}/GoogleService-Info.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
  echo "Staging GoogleService-Info copied."
elif [ "${CONFIGURATION}" = "Release" ]; then
  cp "${PROJECT_DIR}/Configs/${CONFIGURATION}/GoogleService-Info.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
  echo "Production GoogleService-Info copied."
fi
```

これで `/GoogleService-Info.plist` の読み込み場所を変えて反映できました。

### 以上。
iOSの方がAndroidよりもすんなり対応できたけど、証明書とか覚えるの大変だな～～～って印象でした。

読んで頂きありがとうございました！