📱

アプリの強制アップデート機能を過信しない

2023/09/02に公開

概要

モバイルアプリのリリース内容によっては、既存ユーザに対して一斉にアップデートを適用して欲しいタイミングがあるかと思います。
その際に、旧アプリの起動時に 「最新版のアプリに更新してください。」 というようなダイアログを出して

  • 新しいアプリのアップデート取得のためにストアへ誘導
  • このダイアログは閉じず、新アプリにしないと旧アプリの利用は継続できない

という機能を組み込んでいることはしばしばあるでしょう。
こんなヤツです。

この機能の落とし穴について記しておきます。

要約

  • ダイアログが表示されるまでにクラッシュしないか確認する
  • アプリが公開されるまで多少時間が掛かるので注意
  • ダイアログが表示される導線を気にかけておく
  • アップデート先のアプリの品質に注意

前提知識

なぜ強制アップデートが必要か

代表的は例は、API や機能の互換性がなくなったときです。
古いアプリの下位互換を考慮できれば強制アップデートは必要ありませんが、下位互換を考慮するのが大変だったり実現不可能である場合には、強制アップデートを発動することになります。

どんな場合に強制アップデートが必要になるかというと、

  • 必須プロパティの型変更
  • 必須プロパティがなくなった
  • クラッシュをしなくとも、機能体験的に問題がある

などです。

Web アプリケーションの場合、API と Web アプリをほぼ同時にリリースすることができる(数分程度のギャップはあるかと思いますが)ので無視できることが多いかと思いますが、スマホアプリの場合はそうもいかない場合が多いです。

ほかには、API で古いアプリ向けのコードを削除したいケースもあるでしょう。

強制アップデートの仕組みをどうやって実現しているか

実装方法は色々あるかと思いますが、「最低でもこのバージョンを使って!」という情報を

  • API サーバ側
  • Firebase の Remote Config

等で設定して、

  • アプリのメイン画面でその値を取得
  • 実行中のアプリのバージョンと、取得した指定バージョンを比較
  • 実行中のアプリのバージョンが古ければ、ストアに遷移するダイアログを表示

がよくある実現方法です。

落とし穴

ダイアログが表示されるまでにアプリがクラッシュすることもある

例示した画面もそうですが、メイン画面のコンテンツがダイアログの裏側で取得・表示されています。
もし、起動処理やメイン画面のコンテンツ取得処理で旧アプリが新 API と互換性がなければ、ダイアログが表示される前にアプリがクラッシュし、新バージョンに誘導することができなくなります。

対策

ダイアログが表示されるまでの処理は最低限クラッシュしない程度の互換性は保っておく。

具体的には、

  • レスポンスのパースに失敗しないよう、プロパティは削除せずにダミーの値を入れておく
  • 新バージョン用のアプリと旧バージョンのアプリでエンドポイントを分ける
  • 旧バージョンのアプリからのアクセスであれば、従来通りのレスポンスを返す

などが考えられます。

アプリが公開されるまで多少時間が掛かるので注意

API をリリースした直後に、Google Play / App Store の公開処理を行ったからといって、いきなり全ユーザーが新アプリをダウンロードできる状態になるとは限りません。

早くてもストアに反映されるまで約1時間程度掛かるので、その1時間の間に強制アップデートを発動しても、ユーザは新しいアプリをダウンロードできない状態になります。

対策

  • ストア反映を確認してから、サーバ側の値を書き換えて旧アプリに強制アップデートを発動
  • ユーザの利用頻度が低い時間帯に API をリリース

ダイアログが表示される導線を気にかけておく

既にログインしているユーザがアプリ起動直後に表示される画面に、強制アップデートダイアログが表示されるよう仕込んでいるケースが多いでしょう。
しかし、この場合

  • 未ログインユーザの起動画面
  • ディープリンクで直接別画面を起動する

ような場合には、ダイアログが表示されるとは限りません。

対策

  • 特定の画面ではなく、アプリの起動処理にダイアログ表示処理を仕込む

新バージョンのアプリの品質に注意

強制アップデートを発動しない場合、ユーザは徐々に新しいアプリへのアップデートを適用していきます。
新アプリの品質に懸念があるような場合には、アプリストアで用意されている段階的リリースを活用することもあるでしょう。

例えば、1% のユーザだけに新アプリをダウンロード可能な状態にして、目立ったクラッシュがなければ 10% のユーザに新アプリをダウンロード可能な状態にするといった具合です。
もし、1% のユーザに公開した時点で重大な問題があればアップデートのロールアウトを止めて、改修版の開発作業に入ることができます。

ただ、強制アップデートをかける場合は段階的リリースとの併用ができません。

対策

  • 強制アップデートを発動する場合の新バージョンのアプリの品質はしっかり担保した状態でリリースする

その他

雑に列挙しますが、このあたりも頭の片隅に置いておくと良いかと思い共有します。

最新版のアプリを即座にダウンロードできる状況にあるとは限らない

  • 再現条件:月末でギガが足りない&アプリサイズが大きい
  • この場合でも、アプリ内のデータ(メモアプリならメモの内容)を参照したいことはあるでしょう
  • 海外ではまだまだ通信速度が速くない地域もあり、Wi-Fi 環境じゃないとアップデートされないこともあるかも?

同時に端末要件を更新したらアップデートできないユーザもいるかも?

  • 例えば、最新版は iOS 16 以上にして強制アップデートを発動する
    • この場合、iOS 15 のユーザは最新版を適用できない
    • まぁ、iOS 15 がサポート対象外なので十分許容範囲かと思いますがw
  • Android の uses-feature と強制アップデートの併用も要注意
    • 例えば、新バージョンで指紋認証を必須にした場合、指紋認証できない端末はアップデートできない
    • それがメイン機能ならともかく、インストール要件ではなく機能要件にするのが良いかと…

強制アップデートダイアログ以外で告知する

上記の通り、必ずしも強制アップデートダイアログを通じてユーザを新バージョンのアプリへ誘導できるとは限りません。
強制アップデートダイアログで誘導できるのがユーザに負荷がないかと思いますが他にも、

  • メールで事前に告知する
  • 事前にアプリ内のお知らせに掲出する
  • サービスの Web サイトや SNS でもアナウンスする

といった方法も考えられます。

API とスマホアプリだけが互換性を気にするものではない

ここでは API とアプリの互換性の話を中心にしてきましたが、他にも

  • イベントドリブンなインフラアーキテクチャを使っている場合のメッセージの互換性
  • API を公開してシステム構築を可能にしている場合

など、API の後方互換性についてはしっかり考慮する必要があります。

まとめ

強制アップデートダイアログを過信せず、API の互換性も一定は担保しつつ、アプリの機能提供を続けていきましょう!

Discussion