ReactNativeのアプリをiOSでも動作させる
ReactNative + Expoで作ったアプリをiOS、すなわちapp storeでも公開するために作業中です。
クロスプラットフォーム開発が可能なReactNativeですが、いくつかAndroidと同じプログラムでは旨くいかない箇所がありました。
すでにAndroidではアプリを公開していますが、iOSでの開発を進めていくなかで気づく点がありました。忘れないようにこの記事にメモしておきます。
随時増えていくと思いますので、ドンドン追記していきます。
概要
- app.json にiOS関連の記述を追加する
- アイコンは1024
- borderRadiusが効かない場合がある
- elevetionはiOSでは利用不可
- ReactNavigationのStackNavigatorのヘッダースタイルに差異がある
- StatusBar.currentHeightはiOSでは利用不可
app.json にiOS関連の記述を追加する
app.jsonにiOSの記述を追加する必要があります。
https://docs.expo.io/versions/v34.0.0/workflow/configuration/
重要なのは「bundleIdentifier」の項目でしょうか。app storeで管理するIDのようなものです。androidのpackageと同じと考えていいと思います。
"ios": {
"bundleIdentifier": "app storeで登録されるID",
"buildNumber":"1.1.2",
"icon": "./assets/icon_ios.png",
"splash": {
"backgroundColor": "#ffffff",
"image": "./assets/splash.png"
}
},
アイコンは1024
iOS用のアイコンを用意する必要があります。 調べた所、サイズは1024×1024で、角丸にしてはいけない、その他appleが提示する使用に従う必要があります。
上記のようにapp.jsonで専用のものを指定する必要があります。
ビルド時にはこのアイコンをリサイズしてさまざまな画像を用意してくれるそうです。 ビルドをアップロードしたら、app storeで使われるstore アイコン?にもこの画像が利用されました。
borderRadiusが効かない場合
borderRadius属性が聞いていないものがたまにありました。条件は確実なものはわからなかったのですが、borderがあるか・重なっている背景、などが影響しているようです。
以下に参考となる情報がありました。
https://facebook.github.io/react-native/docs/view-style-props#borderradius
結論、iOSの場合はoverflow:'hidden'
を付けることで解決できます。
elevetionはiOSでは利用不可
ドキュメントにも書かれていましたし、サンプルのアプリでも対応されていたのですでに知っていたのですが、styleの「elevetion」属性はAndroidでしか効きません。
iOSで実装する場合は以下のように「Platform」を利用して出し分ける必要があります。 必要であればこれに加えて、「zIndex」を使うことになると思います。
...Platform.select({
ios: {
shadowColor: 'black',
shadowOffset: { width: 0, height: 3 },
shadowOpacity: 0.1,
shadowRadius: 3,
},
android: {
elevation: 20,
},
}),
ReactNavigationのStackNavigatorのヘッダースタイルに差異がある
StackNavigatorで設置されるヘッダーのスタイルに以下2点の差異を見つけました。
-
header領域に枠線がある
header領域とscreen領域の間に枠線がでます。 もともとAndroidではデフォルトでelevetionが効いてました。その代替としてborderが有効になっているのではないかと思います。不要であればStyleで消すことができます。
-
headerTitleStyleに枠線が表示されない
header内のタイトル文字の装飾として下線を表示したかったのですが、iOSでは出来ませんでした。
「headerTitleStyle」で下線を指定すればAndroidでは表示されていたのですが、iOSでは表示されませんでした。解決方法もまだわかっていません。
StatusBar.currentHeightはiOSでは利用不可
keybordAvoidingViewの動作確認時に発見しました。
以下の記述をしていたため、iOSではエラーが発生しました。
keyboardVerticalOffset = {android:Header.HEIGHT + StatusBar.currentHeight}
StatusBar.currentHeight
はAndroidのみで利用できます。ドキュメントにもありました。
https://docs.expo.io/versions/v34.0.0/react-native/statusbar/
Constants currentHeight (Android only) The height of the status bar.
iOSではステータスバーの部分はアプリの領域に含まれていない様子なので、意識しなくとも問題ないようです。
KeyboardAvoidingViewに関しては、OSごとに出し分ける修正を行うことで解決しました。
<KeyboardAvoidingView
style={styles.avoidView}
behavior={'position'}
keyboardVerticalOffset={Platform.select({
ios: Header.HEIGHT, // iOS
android:Header.HEIGHT + StatusBar.currentHeight, // android
})}
/>
おわりに
基本的にはそのまま動作しますが、細かいところでOSの差がでるようです。
とはいえReactNativeは十分にクロスプラットフォーム開発と言えるくらいの精度ですので、とても助かります。 1人で両方のアプリが一度に構築できるというのはとても便利です。
google playとapp storeにも、いくつもフローの違いがあるようでした。 躓いた所はメモしておこうと思っています。