🤖

[ReactNative] 最新バージョンを確認して更新のアラートを表示する方法

2023/01/02に公開

ReactNativeでアプリを作っています。そのアプリでは使用中のバージョンが最新ではなくてユーザーに更新して欲しい場合に、更新のアラートが出るようにしています。今回はその方法をまとめていきたいと思います。

簡単な説明

私が採用した方法を簡単に説明すると以下です。

最新のバージョンをS3においたjsonファイルに記載
使用中のバージョンをapp.jsonから取得
最新のバージョンと使用中のバージョンを比較し、更新可能であれば更新のアラートを表示

詳細

先ほど簡単に説明した方法の詳細を記載していきます。

最新のバージョンをS3においたjsonファイルに記載

以下のようなjsonファイルを作成し、S3バケットにアップします。

{
  "version": "1.0.9"
}

新しいバージョンのアプリをリリースしたときに、このjsonファイルのversionも上げます。
※ 軽微な修正のみでユーザーに更新を促す必要がない場合は、jsonのversionは上げない。

使用中のバージョンをapp.jsonから取得

ユーザーが使用しているバージョンを以下のようにして取得します。

src/config/version.ts
import * as appJson from '../../app.json';
export const version = appJson.expo.version;

最新のバージョンと使用中のバージョンを比較

上記の方法で最新のバージョンと使用中のバージョンを取得します。そしてそれらを比較して使用中のバージョンより新しいバージョンがあるのかを調べます。私は以下の関数hasNewVersionを作成して更新が必要かどうか判断するようにしました。

src/lib/version.ts
export const version2Number = (version: unknown): number | undefined => {
  if (typeof version !== 'string') {
    return undefined;
  }
  const versionString = version.split('.').join('');
  return isNaN(+versionString) ? undefined : +versionString;
};

export const hasNewVersion = (latestVersion: unknown, usingVersion: string): boolean => {
  const _latestVersion = version2Number(latestVersion);
  const _usingVersion = version2Number(usingVersion);
  if (!_latestVersion || !_usingVersion) {
    return false;
  }

  // latestVersionがstring以外なら↑の処理でreturnされるのでas stringを使用
  const splitedLatestVersion = (latestVersion as string).split('.');
  const splitedUsingVersion = usingVersion.split('.');

  let hasNewVersion = false;
  for (let i = 0; i < splitedUsingVersion.length; i++) {
    if (+splitedLatestVersion[i] === +splitedUsingVersion[i]) {
      continue;
    } else if (+splitedLatestVersion[i] > +splitedUsingVersion[i]) {
      hasNewVersion = true;
      break;
    } else if (+splitedLatestVersion[i] < +splitedUsingVersion[i]) {
      hasNewVersion = false;
      break;
    }
  }
  return hasNewVersion;
};

latestVersionがS3から取得した最新のバージョン、usingVersionがapp.jsonから取得した使用中のバージョンです。latestVersionはS3からうまく取得できないケースも考えられるのでunknownにしています。

S3に設定したバージョンが使用中のバージョンより上の場合、アラートを表示させる

App.tsxに以下のようなuseEffectを追加し、アプリ起動時に処理が実行されるようにしました。強制アップデートにはしていないので、Not nowをクリックするとアラートが閉じ、Updateをクリックするとapp storeに遷移するようにしています。

src/App.tsx
...
useEffect(() => {
    fetch(iosJsonPath)
      .then((res) => res.json())
      .then((res) => {
        if (res.version && hasNewVersion(res.version, version)) {
          Alert.alert('Task Management Board became more useful', '', [
            { text: 'Not now' },
            {
              text: 'Update',
              onPress: () => {
                Linking.canOpenURL(appStorePath)
                  .then((supported) => {
                    if (supported) {
                      return Linking.openURL(appStorePath);
                    }
                  })
                  .catch((err) => console.log({ err }));
              },
            },
          ]);
        }
      })
      .catch((err) => console.log({ err }));
  }, []);
...

古いバージョンのアプリを開くと以下のようなアラートが表示されるようになります。

終わりに

S3に置いたjsonから取得したバージョンとapp.jsonから取得したバージョンを比較することで更新が必要か判断するようにしました。しかし私は仕事ではweb開発を行なっており、スマホアプリの開発は行なっていません。なのでこれが正しい方法なのか不明です。もっと良い方法があればコメントで教えてください。

宣伝

私が個人開発で作成したTask Management Boardというアプリは、今回紹介した方法を使って更新を促すアラートを表示するようにしています。以下のリンクからダウンロードできるのでもし良ければダウンロードしてみてください。

https://apps.apple.com/jp/app/task-management-board/id6443765309

どういうアプリか知りたい方は以下のLPをご確認ください!
https://tm-board.hj-pg.com/jp

Discussion