App Splash スクリーン

2020-12-16 hit count image

リアクトネイティブ(React Native)プロジェクトでreact-native-splash-screenを使ってSplashスクリーンを好きな時間に終了するように作ってみましょう。

概要

リアクトネイティブ(React Native)は基本的にSplashスクリーンを提供しています。以前のブログでも紹介しましたが、react-native-makeツールを使ったら簡単に色んなサイズのSplashイメージを作れます。下のリンクはreact-native-makeツールを使ってSplashイメージを作る方法に関するブログです。

しかし、実際アプリを起動したらSplashスクリーンが早く終了されます。普通のアプリではSplashスクリーンを表示して裏で必要な情報をapiで取ってきてSplashスクリーンを終了してその情報を表示する自然なUXを提供するが、リアクトネイティブ(React Native)が基本的に提供してるSplashスクリーンでそうゆう感じのUXを提供することは難しです。

このブログではreact-native-splash-screenライブラリを使ってSplashスクリーンを終了する時点をコントロールして自然なUXを提供するように作ってみます。

インストール

リアクトネイティブ(React Native)でSplashスクリンーんを好きな時終了させるためreact-native-splash-screenライブラリを下記のコマンドでインストールします。

npm install --save react-native-splash-screen

ライブラリ連結

リアクトネイティブ(React Native)でreact-native-splash-screenを使うため下記のコマンドでreact-native-splash-screenライブラリとリアクトネイティブ(React Native)プロジェクトを連結します。

0.60 以上

cd ios
pod install
cd ..

0.59 以下

react-native link react-native-splash-screen

ライブラリ連結失敗

下記のような場合リアクトネイティブ(React Native)にreact-native-splash-screenを連結する時連結がうまくいかなくって失敗する場合があります。

  1. アンドロイドプロジェクトのパッケージ(Package)名を変更した場合。
  2. iOSでPodを使ってる場合。

私は両方使ってるので連結する時結構大変でした。上のような場合、連結が失敗する方は下記の方法を使ってみてください。

  1. アンドロイドプロジェクトのパッケージ(Package)名を変更した場合。 アンドロイドパッケージ(Package)名に合わせてフォルダーの構造を変更します。例えば、パッケージ名がio.github.dev.yakuza.blabooの場合、com/blabooであるフォルダーの構造をio/github/dev/yakuza/blabooで変更します。
  2. iOSでPodを使う場合。 私はほとんどのプロジェクトギット(git)で管理したます。下記の方法は(git)を使った場合です。

下のコマンドでPodを削除します。

  # cd ios
  pod deintegrate
  rm Podfile

下記のコマンドでreact-native-splash-screenライブラリをインストールしてリアクトネイティブ(React Native)プロジェクトへ連結します。

  # React Native root directory
  npm install --save react-native-splash-screen
  react-native link react-native-splash-screen

その後、下記のコマンドでギット(git)を使って削除したPodを戻して再インストールします。

  # cd ios
  git checkout -- Podfile
  pod install

使い方

リアクトネイティブ(React Native)でreact-native-splash-screenを使うためには大きくネイティブ(Native)部分とJS部分へソースを追加する必要があります。ネイティブ(Native)部分はアンドロイド、iOSでSplashスクリーンを実行するためで、JS部分はネイティブ(Native)で実行したSplashスクリーンを終了するためです。

アンドロイド

アンドロイドでreact-native-splash-screenを使うためMainActivity.javaファイルを開いて下記のように修正します。

...
import android.os.Bundle; // here
import com.facebook.react.ReactActivity;
import org.devio.rn.splashscreen.SplashScreen; // here
...
public class MainActivity extends ReactActivity {
   @Override
    protected void onCreate(Bundle savedInstanceState) {
        SplashScreen.show(this);
        super.onCreate(savedInstanceState);
    }
    ...
}

また、アンドロイドで使うSplashスクリーンを生成する必要があります。android/app/src/main/res/layout/launch_screen.xmlファイルを生成して下記のソースコードを追加します。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/launch_screen">
</LinearLayout>

上部で紹介したgenerator-rn-toolbox(Splashイメージ)を使っでSplashイメージを生成した場合はdrawable-*フォルダーにlaunch_screen.pngファイルが生成されます。

したがって上のソースコードをコピペして使っても構いませんが、Splashイメージファイル名が違う場合android:background="@drawable/launch_screen"launch_screen部分を生成したイメージファイル名で変更して使ってください。

iOS

iOSでreact-native-splash-screenを使えためAppDelegate.mファイルを開いて下記のように修正してください。

...
#import "RNSplashScreen.h"  // here

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ...
    [RNSplashScreen show];  // here
    return YES;
}

@end

JS

上で設定したSplashスクリーンを終了させるため下記のようにソースを追加します。

  • Functional Component
import React, { useEffect } from 'react'
import SplashScreen from 'react-native-splash-screen'
...
const WelcomePage = () => {
  ...
  useEffect(() => {
    SplashScreen.hide();
  }, []);
  ...
}
  • Class Component
...
import SplashScreen from 'react-native-splash-screen'
...
export default class WelcomePage extends Component {

    componentDidMount() {
    	...
      SplashScreen.hide();
    }
}

上のソースを見たら分かりますがSplashScreen.hide();を使って好きな時Splashスクリーンを終了させることができます。

完了

リアクトネイティブ(React Native)でプロジェクトを進める時Splashスクリーンがいつも早くなくなって困りました。react-native-splash-screenライブラリを使った後、Splashスクリーンを自由にコントロールすることが出来てもっと良いUXを作ることができました。

私の場合、ネットワークを使ってないアプリは下記のように強制的に時間を入れてSplashスクリーンをもうちょっと維持しています。

  • Functional Component
useEffect(() => {
  setTimeout(() => {
      SplashScreen.hide();
  }, 1000);
}, [])
  • Class Component
componentDidMount() {
  ...
  setTimeout(() => {
      SplashScreen.hide();
  }, 1000);
}

ネットワークを使う場合はネットワークから必要な情報を貰ってSplashスクリーンを終了させています。

皆さんもreact-native-splash-screenを使ってユーザにもっと良い経験を提供してみてください。

参考

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

アプリ広報

今見てるブログを作成たDekuが開発したアプリを使ってみてください。
Dekuが開発したアプリはFlutterで開発されています。

興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。

Posts