Channel surfing for Expo Updates: 実行時にアップデートチャネルを切り替える方法
Ship changes to specific users instantly with Expo's OTA Update Channel Surfing. Now you can switch update channels at runtime without reinstalling.
アプリを再インストールせずに、特定のユーザーに対して即座に変更を配信できたら便利だと思ったことはありませんか?私もです。顧客からの改善要求を素早く実装できても、その成果を検証してもらうにはすべてのユーザーに更新を配信するか(実験的な変更にはリスクがある)、その顧客向けに1回限りのビルドを作る必要がありました(双方にとって手間)。不足していたのは柔軟性です。
開発者は、非技術系ステークホルダーやQA、あるいは必要に応じて全ユーザーなど、異なるユーザーグループに別々のアップデートを配信できることを望んでいました。Productionビルドを作業中のバージョンに切り替えてフィードバックを集め、再びProductionに戻す手段が存在しなかったのです。これを可能にするのが「チャンネルサーフィング」です。
インストール済みのアプリは実行時にアップデートチャネルを切り替えられるため、Productionアプリが固定された終点ではなく、レビューや改善のための柔軟な場になります。特に、既にインストールされている実機環境で変更をテストしてフィードバックを送る必要がある非技術系のステークホルダーにとって有用です。
アップデートチャネルの理解
Update channels(EAS Update のチャネル)は、どのビルドがどのアップデートを受け取るかを決める仕組みです。各ビルドはチャネルに紐づいており、そのチャネルが受信するアップデートを決定します。例えば、preview チャネルにアップデートを公開しても production のユーザーに影響を与えません。
過去はチャネルを切り替えるには別のネイティブビルドをインストールする必要がありました。チャネルについて詳しくは EAS Update ドキュメント を参照してください。
チャンネルサーフィングとは
チャンネルサーフィングは、インストール済みアプリが再インストールなしで異なるアップデートストリーム(チャネル)から取得できるようにする機能です。アプリは実行時にチャネルを切り替え、アンインストールされるか別のチャネルに切り替えられるまで新しく選択したチャネルからのアップデートを受信し続けます。
実務では、プロダクトオーナーやQAがプロダクションビルドを preview チャネルに切り替えて最新の変更を試し、テストが終わったら再度 production に戻す、といった使い方が想定されます。再インストールや別のプレビュー用ビルドは不要です。
内部的には、アプリが updates クライアントにどのチャネルを使うかを通知できるようにしており、その選択は実行時に変更可能で、クリアまたは上書きされるまで有効です。
チャンネルサーフィングの実装方法
まず、プロジェクトが EAS Update に設定されている必要があります。セットアップ手順は EAS Update の getting started guide を参照してください。
チャンネルサーフィングのコアは単一の API 呼び出しで駆動されます。チャネルヘッダーを設定する例:
Updates.setUpdateRequestHeadersOverride({
"expo-channel-name": "your-channel",
});
これは EAS Update に問い合わせる際に使用されるチャネルヘッダーを設定します。API の詳細は setUpdateRequestHeadersOverride を参照してください。
より良いユーザー体験にするには、チャネルを切り替えて次のアプリ再起動を待つだけでなく、すぐに更新を確認してあればダウンロード→リロードする方法が一般的です。典型的なフローは次のとおりです。
- チャネルを変更する(
setUpdateRequestHeadersOverride)
- 更新があるか確認する(
checkForUpdateAsync)
- 更新を取得して適用する(
fetchUpdateAsync)
- アプリをリロードする(
reloadAsync)
以下はこれらを組み合わせたシンプルな例です。
import * as Updates from "expo-updates";
async function channelSurfAsync(selectedChannel: string) {
Updates.setUpdateRequestHeadersOverride({
"expo-channel-name": selectedChannel,
});
const { isAvailable } = await Updates.checkForUpdateAsync();
if (isAvailable) {
await Updates.fetchUpdateAsync();
}
await Updates.reloadAsync({
reloadScreenOptions: {
backgroundColor: "#F8FAFC",
spinner: { enabled: true, size: "large" },
fade: true,
},
});
}
このフローの構成方法は自由です。複数のユーザー操作に分割しても、一度に実行しても構いません。いずれの場合も失敗に備えることが重要です。ネットワーク障害や無効なチャネルによって更新が適用されないことがあります。
チャンネルサーフィングは通常、全員向けに公開するのではなく限定ユーザー向けに公開します。例えば認証された従業員のみ表示されるボタンで preview に切り替える、といった運用が考えられます。
利用可能なチャネルの一覧はアプリ側で定義しておく必要があります。現時点では既存のアップデートチャネルを取得する公開 HTTP API はありません(ロードマップに記載)。したがって、チャネル切替 UI は既知のチャネル名を使うか、自分で eas channel:list を呼ぶエンドポイントを作成してください。
オーバーライドが設定されると、そのデバイス上でアンインストールされるかオーバーライドが上書きされるまで、EAS Updates API はそのチャネルを使ってその後の更新関連操作を行います。
補足:SDK 54 から reloadAsync はリロード中の UI をカスタマイズできるようになり、以前あった短い空白表示のフラッシュを回避できます。これにより、アップデート適用がより意図的でスムーズに感じられます。
チャンネルサーフィングが動作しているかテストする方法
チャンネルサーフィングを実際に確認するにはリリースビルドが必要です。ほとんどの expo-updates API はリリースビルドでのみ利用可能です(EX_UPDATES_NATIVE_DEBUG を有効にしてビルドした場合を除く)。デバッグビルドでは開発サーバーから JavaScript をロードするため通常の更新フローをバイパスします。
利便性のため、EAS Build を使ってテスト用のリリースビルドを作成できます。EAS Build をまだ設定していない場合は EAS Build getting started guide に従ってください。
EAS Build では、プロファイルで明示的に development build(例: developmentClient: true)を選択しない限りリリース設定が使われます。ここではリリース設定は変えずに出力形式だけを変えています:iOS シミュレータアプリ(ios.simulator: true)と直接インストール可能な Android APK(android.buildType: "apk")にすることでローカルでの検証を容易にしています。
{
"cli": { "version": ">= 16.28.0", "appVersionSource": "remote" },
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"channel": "development"
},
"preview": { "distribution": "internal", "channel": "preview" },
"production": { "autoIncrement": true, "channel": "production" },
"production-simulator": {
"channel": "production",
"ios": { "simulator": true },
"android": { "buildType": "apk" }
}
},
"submit": { "production": {} }
}
ビルドを実行します。
eas build --profile production-simulator --platform [ ios/android ]
ビルドが完了したらシミュレータ/エミュレータにダウンロードしてインストールします。
アップデートの公開とチャネル切替
アプリがインストールされたら、別のチャネルにアップデートを公開します。
eas update
その後、アプリ内のチャンネルサーフィング UI に移動してチャネル切替を実行します。例えば production と preview を切り替えるボタンを用意しておくとよいでしょう。チャネル変更を実行すると、アプリは選択したチャネルからアップデートを取得して新しいアップデートにリロードします。
Expo OTA Update に関する注意点
これらはチャンネルサーフィング固有の問題ではありませんが、実行時にチャネルを切り替えると顕在化しやすくなります。
ランタイムバージョンの不一致
アップデートの runtime version がインストール済みアプリの runtime version と一致しない場合、そのアップデートはダウンロードまたは適用されません。チャンネルサーフィング時には、チャネルは切り替わったがアップデートが適用されない(該当チャネルにアップデートがあるはずなのに適用されない)という状況で現れます。これは通常、そのアップデートが別のネイティブバージョンから公開されたことを意味します。
アップデートを削除/元に戻す
既にデバイスがあるチャネルのアップデートをダウンロード済みの場合、EAS ダッシュボードからそのアップデートを削除(または eas update:delete)しても、既にダウンロード済みのデバイスからは削除されません。削除は将来のダウンロードを止めるだけです。
問題のあるアップデートを元に戻す最も確実な方法は、同じチャネルに既知の良好なアップデートを再公開することです。これによりチャネル履歴の先頭に新しいアップデートが作成され、クライアントはそれを最新として適用します。あるいは eas update:rollback を使ってクライアントに以前の安定したアップデートを再適用させたり、ビルドに埋め込まれたアップデートにフォールバックさせたりできます。
チャンネルサーフィングがモバイルの反復を改善する理由
チャンネルサーフィングは、プロダクション環境で素早く変更をレビューする必要がある場合に特に有用です。緊急のバグ修正があり、広くロールアウトする前に検証が必要なケースを考えてください。チャンネルサーフィングを使えば、その変更を特定の少数の指定ユーザーに限定して検証させることができます。
プロダクトオーナーやQAはインストール済みの production ビルドを他のチャネルに切り替えて修正や機能を確認し、終了したら再び production に戻せます。これにより非技術系ステークホルダーをレビューや意思決定に参加させやすくなり、ワークフローもスムーズに保てます。1つの production ビルドがテスト・フィードバック・検証のための柔軟なツールになります。
チャネル切替時のリスクと考慮点
チャネルを切り替えるとアプリが読み込む JavaScript バンドルが変わります。マイグレーションやデータ構造がチャネル間で互換性がない場合、往復で切り替えると問題が発生する可能性があります。例えば、ベータアップデートでデータベースのマイグレーションを行うと、production 側が新しいスキーマを理解できないことがあります。
開発者は次のいずれかを行うべきです:
- 更新がチャネル間で安全に切り替え可能であることを保証する
- 必要に応じて一方向の切替のみを許可する(例:preview から production への戻しを制限する)
リソース
- EAS Update Override update configuration at runtime
- How EAS Update works
- Expo Updates
- eas-cli