React Native Non-React Tips

React に関係ない React Native の tips をまとめる。随時加筆。

## シミュレーター・エミュレーターが立ち上がらない

### iOS

<kbd>react-native run-ios</kbd> だと iOS シミュレーターがうまく立ち上がらない場合、 Xcode をたちあげてから Run ボタンを押すことで実行できる。
<kbd>open .</kbd> で Finder を開いてから `ios/app.xcodeproj` を開く、というのが確実かつ速い。

### Android

VirtualBox と同時にエミュレーターを立ち上げることができないようなので注意。

https://www.virtualbox.org/ticket/14294

Docker for Mac なんかも衝突するので、立ち上がらないなと思った場合は仮想環境が悪さしてないかチェックするといい。


## React Native のバージョンをアップグレードする

flow を有効にしてると少しめんどくさい。次の手順でやってる。

1. `package.json` の `dependencies` で `react-native` のバージョンを指定する
    - その他 `react`, `react-addons-test-utils`, `react-dom`, など依存するパッケージのバージョンもあわせてやる
2. <kbd>cd /tmp && react-native init a</kbd> してできた `/tmp/a/.flowconfig` とプロジェクトルートの `.flowconfig` をみくらべて追従する
    - 特に flow のバージョンがひとつでも違うと標準コンポーネントでエラーが出たりするので厳密にあわせること
3. flow を流して怒られたところをなおす

つまり flow は常に最新バージョンが使えるわけじゃなく、 `react-native` が使っているバージョンに縛られる。この点はちょっとイケてないんだけど、いまのところ React Native は 2 週間単位でのリリースになっているので flow で使いたい機能があっても少し待てば使えるようになる。


## アプリの表示名を変える

![display-name.png](https://qiita-image-store.s3.amazonaws.com/0/27516/ca35ad0d-da9a-5d4d-8e88-e09fe3e168c7.png)

### iOS

Xcode プロジェクトの設定から変更する。

1. 左側のプロジェクトナビゲーターから `Info.plist` を選択する
2. "Bundle display name" を追加し、表示したい名前を指定する

<img width="1181" alt="ios-rename.png" src="https://qiita-image-store.s3.amazonaws.com/0/27516/899b1d54-201d-e3c0-4914-3bdd583b0d4e.png">

### Android

`android/app/src/main/res/values/strings.xml` の中の `app_name` 要素のテキストを変更する。

```xml
<resources>
    <string name="app_name">TODO</string>
</resources>
```

### 注意

http://stackoverflow.com/questions/32830046/renaming-a-react-native-project/37959668

↑ページの <kbd>react-native upgrade</kbd> を使う方法だと iOS/Android それぞれで新規プロジェクトファイルが作成されてしまっていままでの設定がすべてやり直しになる
というかこれはその名の通り、 react-native 自体のバージョンアップグレードをするためのコマンドなのでこの用途で使うのは間違い。


## アプリのアイコンを変える

### iOS

1. アプリの中の `Images.xcassets` を開く
2. AppIcon を選択
3. iPhone Spotlight, iPhone App にサイズ調整したアイコンをドラッグ & ドロップ

<img width="1181" alt="ios-icon.png" src="https://qiita-image-store.s3.amazonaws.com/0/27516/d22eb002-4733-0ea5-463b-77412242a549.png">

アイコンのサイズは次のようにあらかじめリサイズする。
iOS5, 6 は React Native サポート対象外なので設定は必要なし。

<table>
    <thead>
        <tr>
            <td></td>
            <th>2x</th>
            <th>3x</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th>iPhone Spotlight</th>
            <td>80 x 80 px</td>
            <td>120 x 120 px</td>
        </tr>
        <tr>
            <th>iPhone App</th>
            <td>120 x 120 px</td>
            <td>180 x 180 px</td>
        </tr>
    </tbody>
</table>

### Android

`android/app/src/main/res/` 以下の次のファイルを変更する

- `mipmap-mdpi/ic_launcher.png`
- `mipmap-hdpi/ic_launcher.png`
- `mipmap-xhdpi/ic_launcher.png`
- `mipmap-xxhdpi/ic_launcher.png`

それぞれのサイズは次の通り

| mdpi | hdpi | xhdpi | xxhdpi |
| --- | --- | --- | --- |
| 48 x 48 px | 72 x 72 px | 96 x 96 px | 144 x 144 px |


## iOS 起動時のスプラッシュで Powered by React Native と表示させない

Android はスプラッシュ表示がないので設定も必要なし。
起動時にプロジェクト内にある `LaunchScreen.xib` が表示されるので、これを変更する。

http://www.tejitak.com/blog/?p=1289

↑ページを参考にロゴなんかを表示しておくといいかも。


## apk を実機にインストールできない場合がある

Android の問題。機種と Gradle のバージョンの組み合わせよってはインストールできないことがある。手元でこの問題を確認したのは Freetel 雅 FTJ152C 。

↓を参考に `android/build.gradle` 内の Gradle のバージョンを 1.3.1 から 1.2.3 に変更する

https://github.com/facebook/react-native/issues/2720

```gradle
        classpath 'com.android.tools.build:gradle:1.2.3'
```


## iOS と Android で挙動の違うコンポーネントや API を定義したい

↓でプラットフォームごとに拡張子で処理を切り分ける方法が紹介されているのでそれを利用する。

https://facebook.github.io/react-native/docs/platform-specific-code.html#platform-specific-extensions

Platform モジュールで処理を切り分ける方法も紹介されているけど、これは極力使わずに拡張子で切り分けたほうがいいかも。というのも bundle するときに対象プラットフォーム以外のファイルは無視してくれるので速度・サイズ的に有利、なはず。

### ↑でファイルを切り分けると ESLint から import/no-unresolved で怒られる

次のページを参考にして .eslintrc に解決する拡張子を追加してやる。

https://github.com/benmosher/eslint-plugin-import/issues/279

```yml:.eslintrc.yml
settings:
  import/resolver:
    node:
      extensions:
        - .js
        - .android.js
        - .ios.js
```

### ↑でファイルを切り分けると flow からも Required module not found と怒られる

flow の issue で解決方法があがってた。

https://github.com/facebook/flow/issues/945

```conf
[options]
module.file_ext=.android.js
module.file_ext=.ios.js
module.file_ext=.js
```

## "babelHelpers.asyncToGenerator is not a function" というエラーが出る

自前で `.babelrc` を定義していると発生する。次を参考に、 babel-preset-react-native-stage-0 を使う。

https://github.com/facebook/react-native/issues/4844#issuecomment-204035720

```sh
npm install --save-dev babel-preset-react-native-stage-0
```

してから `.babelrc` の presets で react-native-stage-0 を指定する。

```json:.babelrc
{
    "presets": [
        "react-native-stage-0"
    ]
}
```


## bundle キャッシュをクリアしたい

↑のように `.babelrc` を変更したあとなんかはキャッシュがきいてしまって新しく指定した presets を反映して bundle しなおしてくれない。ので次のコマンドで手動でキャッシュをクリアする。

```sh
npm start -- --reset-cache
```

サーバーが立ち上がっちゃうけど必要ないなら <kbd>Ctrl+c</kbd> で落とせば大丈夫。