React NativeでiOS, Androidのストア公開のTips

# 最初に

忘れてはいけない、でも目を背けがちなストア公開を記事にします。
私の場合ですが、web案件がメインだったため、社内に詳しい人物がおらず調べながらストア公開をしました。
また、ReactNativeをやるということは、何かしらWeb開発の経験がある人が多そう。共通課題と思っています。

私の場合、

* RNで知見が少ない
* そもそもWeb開発がメインだからストア公開とかヤベェ。
* iOSはやったことあるけど、Android知らねえや(一方のみ)

などで、事前に時間がかかるだろうと、2週間程度余裕を見まして、開発と並行してリリース準備を進めました。
Tipsとして残したいと思います。

* 尚、記憶を頼りにソースを見て書いてます。間違い&指摘があればすみません。すぐに直します。

今回は以下を前提としています。

* 開発環境 Mac OS X El Capitan
* React Native ver 0.28(以降も流れ自体は変わらないとは思いますが)

# 大前提 開発者登録は出来てますか？
当然のことですが、App Store、google playにアプリを出すにはデベロッパー登録が必要です。
Androidは\$25/初回登録、iOSは\$99/年間 必要となります。

登録手順のStepは各所で公開されているのでググって調べましょう。
[Google Play Developer登録手順](http://tkhsken.hatenablog.com/entry/2015/07/13/201542)
[iOS Developer Program登録手順](http://examination-03.hatenablog.com/entry/2014/08/11/002611)

# 公開の準備をする
公開用のbuildを作成する前に、アプリ情報を入力する必要があります。

## Android 
### Manifestfileを変更
android/app/src/main/AndroidManifest.xml 
変更が必要あるのは

* android:versionCode (内部の番号google playにuploadするたびインクリメントが必要)
* android:versionName (google playで表示されるversion番号)
* android:label="@string/app_name" (アプリ名)
* android:icon="@mipmap/xxxxxxx" (ランチャーに表示されるアイコン)

android/app/src/main/res/values/strings.xml
に参照があるので変更すると良いでしょう。

### build.gradle を変更
Manifestfileとbuilde.gradleを合わせるようにしています。

```groovy
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        multiDexEnabled true
        applicationId "com.yourapplicationId"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 3
        versionName "1.0.1"
        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
        renderscriptTargetApi 20
        renderscriptSupportModeEnabled true
    }
```

### アイコンを作成
Androidのiconを作成します。解像度によったアイコンを準備してあげる必要があります。
一つずつ作るのは手間がかかりすぎるので、次のような[Icon generator](https://makeappicon.com/)を使用すると時間短縮になります。
MakeAppIconは「1536x1536px」で画像を用意するとそれぞれの解像度にあったiconを作成してくれます。
それらを各フォルダに配置し、android:iconを設定します。

※ google playに登録用のアプリアイコンも作成されます。後々使います。

## iOS
### iOSプロビジョニングプロファイルの更新
iOSの場合は正規開発者がbuildしたものか、悪意のあるアプリが公開されないか。というところが徹底されていると感じます。
それが、プロビジョニングプロファイルの作成の面倒に繋がると思います。
全てこの記事では説明できない + iOSアプリでも共通項目のため下記を参照してください。

詳しくは以下(初見では手順9,10行くまでにめちゃくちゃハマりました。。。)
http://qiita.com/siglab/items/c3f8560fbafd44ad7633
http://qiita.com/edo_m18/items/6f10e57f95b25d9dab4e#%E6%89%8B%E9%A0%86

正直、プロビジョニング周りははてなが多いです。図解してくれる記事があったので助かりました。
全然サインアップができない。。。と頭抱えていたら、Bundle Identifierの間違いだったことがあります。
http://qiita.com/fujisan3/items/d037e3c40a0acc46f618

### Info.plistを編集する
Project > Target > General > Identity
でアプリ名や、Version、buildを設定します。
<img width="574" alt="スクリーンショット 2016-12-19 20.21.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/56423/7cdea13d-b7f1-04e6-8180-334c36386174.png">
Bundle IdentifierはApple Developerで証明書を作成した名前と合わせてください。

### Signingを行う
Signingを行う前に、Developer Teamで登録されている。Teamがあるか確認してください。
ない場合は、Xcode > Preferences > Accounts > Apple IDsを追加してください。

[XcodeのSigning機能](http://dev.classmethod.jp/smartphone/xcode-8-signing/)を使用すると自動化され便利です。
Project > TARGETS > General > SigningからAutomatically manage signingにチェックします。
すると、Teamがでてくるので、Teamを選択します。

<img width="628" alt="スクリーンショット 2016-12-19 21.02.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/56423/d8dbc4e9-e4b7-3f3c-d6f1-41a430bdd8c4.png">

### アイコンを作成
iOSのiconを作成します。Androidと同じく解像度によったアイコンを準備してあげます。
iconはImage.xcassetsに設定します。
<img width="583" alt="スクリーンショット 2016-12-19 20.13.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/56423/d9e27d64-6826-d1ae-3a02-c457034eaa66.png">

# 公開用のbuildを作成する
公開用に署名されたbuildを作る必要があります。

## Android
buildを作成し、デジタル署名する必要があります。
基本的な流れは[Guide](http://facebook.github.io/react-native/docs/signed-apk-android.html)で確認できます。

### keystoreを作成
デジタル署名用のkeystoreを作成します。

```sh
keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
```
開発者の情報、パスワードなどを入力してkeystoreを作成してください。
※ 尚、このkeystoreを紛失 or パスワードを忘れると、apkを更新できず大変なことになるので必ずどこかに控えましょう。

### buildを作成
gradleの機能を利用して、buildを作成することができます。
androidフォルダに移動し、以下のコマンドを叩きます。

```sh
cd android && ./gradlew assembleRelease
```

以下のファイルが作成されます。
android/app/build/outputs/apk/app-release-unsigned.apk

### デジタル署名を行う。
release用のファイルは作成されましたが、公開するにはデジタル署名を行う必要があります。
先ほど作成したkeystoreを使用し、署名を行います。

```js
jarsigner -verbose -keystore my-release-key.keystore app/build/outputs/apk/app-release-unsigned.apk my-key-alias
```

### zipalignを行う。
コンソールから作ったapkはzipalignを行う必要があります。(IDEの時は自動らしい)
これは、apkを最適化し、実行時のRAMの軽減をしてくれます。お約束事なのでやっておきましょう。

```sh
zipalign -f -v 4 app/build/outputs/apk/app-release-unsigned.apk my-app.apk
```

参考
http://qiita.com/androhi/items/9c7340d709e856f9b71e

AndroidはreleaseBuildの作り方がわからず戸惑いましたが、
やり方さえ確立できれば、リリースの際に手こずった印象はなかったです。
Debug Buildを始めて通す時が大変だった印象。。。

## iOS
iOSは準備が大変な分、ビルドの方法はシンプルだった印象です。

### アプリをアーカイブする
Product > Archive を選択します。
グレーの場合はビルドターゲットをシュミレータから変更しましょう。
<img width="348" alt="スクリーンショット 2016-12-19 21.09.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/56423/ea88fea5-f465-5565-1e87-6a0ccc464ce1.png">

以上!!!
と言いたいところですが、初アーカイブできるまで何度か設定周りを触った印象です。。。
一つ一つメモっておけばよかったのですが、余裕がなくてできていませんでした。
ただし、ログをググるとReact Nativeのissueに上がってたと思います。

Libraries周りのBuild Settingsを触った覚えもあります。

# 公開手順

## Android
1.　[google play developer console](https://play.google.com/apps/publish/)にアクセスします。
2.　Create applicationをクリックしてアプリを作成
3.　APK > 製品版に最初のAPKをアップロードをクリックでapkをupload
4.　必要項目(*)を入力して(アプリ名やスクリーンショットやその他もろもろ)

ここでは書ききれないので下記などを参考にしてください。
http://dev.classmethod.jp/smartphone/android/android-app-how-to-release/

## iOS
1. [iTune Connect](https://itunesconnect.apple.com/) > マイ App > + > 新規App
2. バンドルIDを一致させたアプリを作成します
3. Archiveが成功するとリストが表示されるので　 > 選択 > Upload App Storeを選択します。
4. 有効なTeamを選択し、Validationを行います。
5. 成功すれば、自動的にuploadされます。

以前の記憶では何かのUploaderを使用した覚えがあるが、Archive、これは便利。
バンドルIDが不一致の場合、情報が少ないエラーに泣かされるので注意(笑)

図解でわかりやすいです。
https://iphone-app-tec.com/ios/app-upload.html

# まとめ
手順自体はついつい忘れがちなので、忘れ防止に書いたが既に忘れてて笑った(笑)

React Nativeだからというところは少なく、
AndroidとiOS特有のものが多いです。逆に言うとiOS & Android ディベロッパーが近くにいるとアドバイスくれるかも。
エラーは仕方ありません。素直に[issue](https://github.com/facebook/react-native/issues)を漁りましょう。