アプリを公開した後にバグが見つかるというのは、想像したくない状況です。
もしバグが見つかれば、バグを修正し、新しいバージョンを作成して、Google Play StoreとApp Storeにアップロードする必要があります。その際、ストアからリリースの承認が出るまで待つ必要があり、リジェクトされる可能性もあります。リジェクトされれば、また新しいバージョンを作成し、承認されるまで、この流れを繰り返す必要があります。
アプリ開発に関係する人の多くは、この状況を経験しており、それがいかに非効率的であるかを、身をもって知っています。
しかし現在では、ストアに公開せずにアプリを修正するソリューションが誕生しています。Sorebird[1]はFlutter[2]用のCodePushソリューションで、現在はAndroidとiOS用に提供しています。
Sorebirdは、Flutterの専門家と一緒に構築されました。以下が、そのメンバーです。
・Eric Seide氏:
Flutterの創設設者で、GoogleのFlutter/Dartの元エンジニアリングディレクター。
・Felix Angelov氏:
Bloc&Masonの生みの親であり、Very Good Venturesの元主任エンジニア。
・Bryan Oltman氏:
Googleの社内向けエンタープライズFlutterチームの元アーキテクチャリーダー。
・Erick Zanardo氏:
Flutter & Dart GDEで、Flame Coreメンバー。以前はVery Good Venturesに在籍。
モバイルアプリ開発の世界は絶えず進化しており、迅速なアップデートとシームレスなデプロイの必要性が、様々なツールやテクノロジーの革新を後押ししてきました。
この状況に大きな影響を与えたツール1つがCodePushです。
当初Microsoftによって導入されたCodePushは、年々進化し、モバイルアプリケーション向けに効率的なOver-the-Air(OTA)アップデートを求める開発者にとって極めて重要なソリューションとなりました。
本ブログでは、CodePushの歴史と進化を掘り下げ、その起源、主要なマイルストーン、現状を解説します。
【 CodePushの起源 】
CodePushは、モバイル開発者が直面する共通の課題である、アプリストアを通じてアップデートを配信するという、煩雑なプロセスを解決する必要性から生まれました。従来、開発者はアップデートをユーザーに届ける前に、アプリストアの承認が必要で、これにより遅延が発生し、ユーザー体験を損なっていました。この課題に対応するため、Microsoftは2015年にVisual Studio App Centerスイートの一部としてCodePushを導入し、更新プロセスを簡素化し、コード変更のリアルタイム展開を可能にすることを目指しました。
▼
【CodePush の進化】
〈 最初のリリース(2015年)〉
CodePushは、開発者がモバイルアプリに直接アップデートをプッシュできるクラウドサービスとしてリリースされました。React NativeとCordovaをサポートし、これらのフレームワークを使用する開発者にシームレスな体験を提供しました。この最初のリリースは、アップデートの配信に必要な時間と労力を大幅に削減したため、大きな反響を呼びました。
▼
〈 Visual Studio App Centerとの統合(2017年)〉
包括的なモバイル開発ソリューションを提供するというMicrosoftの幅広い戦略の一環として、CodePushがVisual Studio App Centerに統合されました。この統合により、分析、クラッシュレポート、自動テストなどの機能が追加され、アプリのライフサイクル全体を管理する統合プラットフォームが実現しました。
▼
〈 より多くのフレームワークのサポート(2018 ~ 2019年)〉
モバイル開発者の多様なニーズを認識し、CodePushはIonicやXamarinなどのより多くのフレームワークのサポートも拡大しました。この動きにより、ユーザーベースが拡大し、モバイルアプリのアップデートのための汎用的なツールとしての地位が強化されました。
▼
〈 コミュニティ貢献とオープンソース(2019年)〉
Microsoftは、コミュニティ貢献とコラボレーションを促進するために、CodePushクライアントSDKをオープンソース化することを決定しました。この決定により、ツールの機能が強化されただけでなく、共同の取り組みを通じてツールの継続的な成長と改善が保証されました。
▼
〈 機能強化とパフォーマンスの改善(2020 ~ 2022年)〉
長年に渡り、CodePushはパフォーマンス、セキュリティ、ユーザビリティを向上させるために、いくつかの機能強化を行いました。これらの改善には、ロールバックメカニズムの改善、アップデート配信速度の向上、よりしっかりとしたエラー処理などが含まれ、開発者とユーザーの両方にとってスムーズに利用できるようになりました。
日々変化するモバイルアプリ開発の世界では、タイムリーなアップデートをユーザーに提供することが重要です。しかし、CodePushのようなツールがなければ、開発者はいくつかの大きな課題に直面します。
【 手動アップデートプロセス 】
開発者は、アプリストア (Apple App StoreとGoogle Play Store) にアップデートを提出し、承認を待つという従来のアプリストアのアップデートプロセスに頼らざるを得ません。これは時間のかかるプロセスであり、アプリストアの審査待ちの数やアップデート内容次第では、数日から数週間かかることもあります。
【 バグ修正の遅れ 】
重大なバグやセキュリティ上の脆弱性が発生した場合、アプリストアの承認が遅れると、ユーザーが長期間危険な状態に晒される可能性があります。これにより、ユーザー体験の低下、否定的なレビュー、潜在的なセキュリティリスクに繋がる可能性があります。
【 ユーザーベースの断片化 】
ユーザーはアプリを様々なタイミングでアップデートする傾向があるため、様々なバージョンのアプリが同時に使用され、ユーザーベースが断片化します。開発者は問題の診断・解決と合わせて、アプリの複数バージョンを考慮する必要があるため、サポートとデバッグの作業が複雑になります。
【 リソース集約型 】
従来のアップデートプロセスでは、更新が適切にパッケージ化され、テスト、提出されるように、開発者とQAチームが時間と労力を費やすなど、多くのリソースが必要でした。さらに、展開スケジュールを管理し、マーケティングチームやサポートチームと調整する必要があるため、複雑さが増します。
【 A/Bテストができない 】
CodePushのようなツールがなければ、A/Bテストや新機能の段階的な展開は困難です。開発者は、一部のユーザーに素早くアップデートを配信して、フィードバックを集め、データに基づいた意思決定を行う柔軟性に欠けます。
【 関係者との関連性 】
この問題は、モバイルアプリ開発者、プロジェクトマネージャーなど、モバイルアプリ業界のビジネス利害関係者に非常に関連しています。具体的には、以下のような影響があります。
・開発者とQA チーム
これらのチームは、従来のアップデートプロセスの非効率性と遅延の影響を直接受けています。重大なバグ修正や機能リリースに対処する際に、作業負荷やストレスが増加します。
・プロダクトマネージャー
アップデートの提供が遅れると、製品ロードマップを混乱させ、ユーザーからのフィードバックや市場の需要に迅速に対応できなくなります。これは、アプリの競争力やユーザー満足度に悪影響を及ぼしかねません。
・ビジネス関係者
問題発生に、迅速な対応や新機能の提供ができないと、ユーザー定着率の低下、アプリ評価の低下、潜在的な収益損失に繋がる可能性があります。シームレスなユーザー体験を確保することは、高いブランド評価を維持し、ビジネス目標を達成するために極めて重要です。
・エンドユーザー
エンドユーザーは、アップデートの遅延、バグやセキュリティの脆弱性、一貫性のないアプリ体験に不満を募らせます。その結果、エンゲージメントが低下し、アプリ利用離れの可能性が高まってしまいます。
まとめると、CodePushのようなツールがないと、モバイルアプリの開発・保守に関わるすべての関係者にとって大きな問題を引き起こします。これらの問題に取り組むことは、効率性の向上、ユーザー満足度の向上、市場での競争力の維持に極めて重要です。
ShorebirdのCodePush製品で使用される概念を解説します。
・CodePush
CodePushは、「over the air updates」(OTA) とも呼ばれ、Flutter開発者がアプリのアップデートを本番環境でデプロイできるようにするクラウドサービスです。Shorebirdは現在AndroidとiOSで動作しており、最終的にはFlutterが動作するすべての場所で動作する予定です。
「CodePush」は、Microsoft[3]そしてExpo[4]のReact Nativeコミュニティ向けに提供するデプロイ機能の名前にちなんだもので、どちらもFlutterをサポートしていません。
・パッチ適用
パッチ適用とは、ユーザーがApp StoreやPlay Storeから新しいバージョンをダウンロードすることなく、アプリケーションのコードを更新するプロセスです。これは、OTAで適用できるアプリケーションのコード変更のセットであるパッチを作成することで行われます。
パッチに含めることのできる変更の種類は以下の通りです。パッチはアプリケーション内の任意のDartコードを変更できます。
・アプリコード
・生成されたコード
・ネイティブ コードの変更が含まれていない限り、pubspec.yaml 内の依存関係。
パッチはアプリケーション内の任意のDartコードを変更できます。また、これには以下のものは含まれません。
・画像ファイルなどのアセットファイル。ただし、近い将来にサポート予定です(参考:https://github.com/[5])
・ネイティブコード(例:AndroidのJava / Kotlin、iOSのObjective-C / Swift)
・Flutterエンジンの変更 (アプリのFlutterバージョンの変更など)
▼ 関連記事 ▼
・アプリケーション
アプリケーションは、「flutter create [app_name]」を実行することで作成され、App StoreまたはPlay Storeのリストに相当します。各アプリケーションは、「shorebird init」を実行すると割り当てられる一意の「app_id」を持っています。アプリケーションのIDは、プロジェクトのルートにある「shorebird.yaml」ファイルで確認できます。アプリケーションは、0個以上のリリースを持つことができます。
※ 注意:ビルドフレーバーを使用するアプリケーションは、フレーバーごとに一意の「app_id」を持ちます。
・リリース
リリースとは、バージョン番号とビルド番号で識別される、アプリケーションの特定バージョンでます(例:1.0.0+1)。CodePushはApp Storeや Play Storeの外で配布されるアプリにも対応していますが、リリースは通常、App StoreやPlay Storeに公開されるアプリの特定バージョンに対応します。リリースは、「shorebird release [platform]」を実行することによって作成されます。ここで、「platform」は「android」、「aar」、または「ios」です。
・パッチ
パッチとは特定のリリースに対する変更点のことで、OTAアップデートとして適用されます。例えば、パッチはバグ修正や新機能などです。1つのリリースに対して複数のパッチを公開できますが、一度にアクティブにできるパッチは1つだけです。パッチは、関連するリリースのバージョンとパッチ番号(オートインクリメントの整数)によって識別されます。アプリケーションが起動すると、利用可能なパッチがないかチェックされ、最新のパッチが適用されます。このパッチは、次回アプリケーションを起動したときに表示されます。パッチは、「shorebird release [platform]」を実行することによって作成されます。ここで、「platform」は「android」、「aar」、または「ios」です。
・アーティファクト
アーティファクトとは、ビルドやパッチを実行した時に出力されるものです。例えば、「shorebird release android」は、複数のアーキテクチャ特有の「libapp.so」ファイルとAndroidアーカイブ (.aab) ファイルを生成してアップロードします。これらはリリース アーティファクトです。「shorebird patch android」は、パッチ適用時のDart コードと関連付けられたリリースのコード間の際をキャプチャする差分ファイルを生成してアップロードします。これらが、パッチアーティファクトです。
ShorebirdはAndroidとiOSで利用でき、App StoreとPlay Storeでは、約1,000個のアプリが、Shorebirdを使用しています。
特に大きなポイントとして挙げられるのが、「リンクパーセンテージ(iOS) 」です。
App Storeのガイドラインに準拠するため、ShorebirdはiOS上でパッチ内の変更されたDartコードを実行するためにインタープリターを使用します。このインタープリターは、CPU上で実行するよりも約100倍遅く動作します。パッチを速く実行するために、ShorebirdはDartコンパイラとランタイムを変更し、変更されたコードのみをインタープリターで実行し、変更されていないコードはCPUで実行できるようにしています。この判断は、関数単位で行われます。
CPUとインタープリターでどのコードを実行するかを決定するプログラムは「リンカー」と呼ばれ、この割合を「リンクパーセンテージ」と呼びます。
このシステムは大部分の時間で非常にうまく機能し、Shorebirdは90%以上のDartコードをCPUで実行できます。しかし、リンカーが不必要に多くのコードをインタープリターで実行するような状況もいくつかあります。
既知のリンカーの問題には、iOSでの低いリンクパーセンテージが含まれます。
結論として、Flutterという高機能な開発フレームワークとShorebirdの継続的デプロイメント機能を組み合わせることで、モバイルアプリの更新に関する従来の課題に向けた包括的な解決策が提供されます。
これらのツールを活用することで、開発者はシームレスで効率的、かつユーザー中心のアプローチでアプリの開発・保守を行い、最終的には競争の激しいモバイルアプリ市場で成功を収めることができます。