コンテンツへスキップ
2026年8月8日 · 出荷

ネイティブの苦痛のないネイティブアプリ

この記事は公開時点の製品について説明しています。最新の機能についてはAI BuilderおよびAgent Teamsをご覧ください。

ネイティブの苦痛のないネイティブアプリ

たとえば、数週間かけてチャットでToDoリストアプリを作っているとします。今のところWebサイト——Reactとデータベースだけの、シンプルな構成です。そこで「Android版を作って」と入力してEnterを押します。ここからその.aabファイルがダウンロードフォルダに現れるまでに実際に何が起きているのか、多くのプラットフォームはこの部分を見せてくれません。そして、隠されているその部分こそが、これまで苦労の元凶だった場所です。

Androidの.aab

まずGradleが処理を引き受けます。アプリのネイティブモジュール——カメラアクセス、ローカルストレージ、ビルドが取り込んだあらゆるプラグイン——はそれぞれどのNDKバージョンでコンパイルされたかを宣言しますが、それらの宣言は常に一致するとは限りません。NDK r25でビルドされたモジュールが、r26を前提としたモジュールとのリンクを拒否する場面を見たことがありますが、そのときのエラーは「バージョンの不一致」とは言わず、.soファイルの奥深くで何かのシンボルが見つからないとだけ表示されます。Kotlinのバージョンはさらに厄介で、あるGradleモジュール内でピン留めされたバージョンが、ビルドスクリプルの先頭で宣言されたバージョンを密かに上書きしてしまうことがあり、ビルド自体は成功します——ただし、特定のAndroidバージョンの実機でクラッシュするバイナリが生成されるのです。これは何も特殊なことではありません。ネイティブAndroidを出荷する上での標準的な「税金」であり、だからこそチームは「今週のエラーを消すフラグ」を知っているためだけの担当者を雇うのです。

ここでのビルドは本物のツールチェーンを実行し、その解決作業を自ら引き受けます。

15〜25分ネイティブコンパイル工程、本物のGradleツールチェーン
  • 依存関係の競合を、実行時クラッシュになる前に検出
  • 新しい失敗が起きるたびに学習し、改善されていくツールチェーン設定

実際のGradleタスクを実行せずに.aabの体裁だけ整える、より速い偽物のバージョンなら1分未満で完成するでしょう。しかし、アプリがバックグラウンドサービスやネイティブの暗号化ライブラリを必要とした瞬間に破綻し、Playストアの審査で即座に指摘されるはずです。私たちはその20分を惜しまない方を選びます。

macOSの.dmg

このファイル1つに2つのビルドが組み込まれています。Xcodeのコマンドラインツールが、Apple SiliconバイナリとIntelバイナリを別々にコンパイルし、その後 lipo それらを1つのユニバーサル実行ファイルに結合します。

90%以上の新規Mac販売がApple Silicon

1つのバイナリだけを出荷して終わりにしたくなる誘惑はありますが——多くの人が自分で選んだのではなく勤務先支給のノートPCを使っており、それが3年前のIntel搭載機である可能性があることを思い出すと、話は変わってきます。ユーザーに自分のチップの種類を調べさせる代わりに(ほとんどの人はわかりません)、私たちは両方を出荷し、OSに黙って選ばせます。代替案として、初期に試したのはLinuxマシンからエミュレートされたツールチェーンを使ってすべてをクロスコンパイルする方法です。その方が速いのは確かです。ただし、出荷から6週間後に実機のmacOS 12でしか現れないコード署名のエッジケースに行き着き、アプリが開かない理由がわからず困惑したユーザーから報告を受ける羽目にもなります。

Windowsインストーラー

ここが、初回起動時の体験がユーザーのアプリへの信頼を左右する分岐点です。Windows SmartScreenはまだあなたのインストーラーを知りません——Microsoftのサーバーとの間に信頼実績がまだ蓄積されていないためです——そのため「Windows によって PC が保護されました」という青い画面が表示され、太字の「実行しない」ボタンと、ほとんど見えない「詳細情報」リンクが並びます。そのリンクをクリックすると「実行」ボタンが現れます。macOSも同様の儀式を独自に用意しています——右クリック、開く、確認、というのも、App Store外のアプリはデフォルトでは信頼されないためです。以前はこの両方を汎用的なFAQページにリンクしていました。しかしサポートチケットから、それではうまくいかないことがわかりました——ダウンロードがマルウェアかもしれないと表示された画面を見た人は、ドキュメントを読みには行かず、スクリーンショットを撮って「ハッキングされたのか」と尋ねてきます。そこでインストールフローがOSを検出し、必要な正確な3クリックをFAQなしで表示するようにしました。細かい点ですが、ファイル自体の名前も重要です——ダウンロードされるファイルはビルド成果物の名前ではなく、あなたの製品名にちなんで命名されます。誰も「app-release-signed-v2-final.exe」をダウンロードしてしまい、それが正しいものかどうかわからないとチャットサポートで説明する必要はないはずです。

ブラウザ拡張機能のマニフェスト

これはパイプライン全体の中で異色な存在です——Gradleもなければ、NDKもなく、通常の意味でのコンパイル工程もありません。その代わりにあるのがマニフェストであり、これは直接話すことのないChromeウェブストアの審査担当者との交渉です。

要求される権限審査結果
<all_urls>(機能に必要な範囲より広い)何に異議を唱えているのか明言しない相手との2週間にわたるやり取り
activeTab(実際に必要な範囲に限定)当日中に承認

MV3はさらに、MV2では容易だったことを複雑にしています——バックグラウンドのサービスワーカーは設計上タスクの途中でもアンロードされます。これはバッテリー寿命を狙ったGoogleの方針であり、そのアンロードを乗り越えて動作し続ける必要がある機能は、それに逆らうのではなく、それを前提に設計しなければなりません。私たちはすべての拡張機能を、実際の機能が必要とする最も狭い権限セットにデフォルトで設定し、特定の機能がそれを求めたときにのみ拡張します。

キーストア

Androidビルドの裏側には、決して目にすることはないものの絶対に失ってはならない成果物が1つあります——署名鍵です。これを失うと、アプリを更新できなくなるだけではありません——既存のIDのもとで更新する能力を、Googleが決して認めてくれる復旧手段もないまま、永久に失うことになります。地味なインフラです。ただのファイルです。しかし、それが半年後のバージョン6をシームレスな更新として出荷できるか、それともインストール数もレビューもゼロから始まる全く新規のリスティングとして出荷することになるかの分かれ目です。私たちはプロジェクトごとに鍵を1つ生成し保管することで、将来のあらゆるビルドが初日と同じ鍵で署名されるようにしています。

その根底にあるチャットスレッド

上記のいずれも、別立ての「モバイルプロジェクト」として存在しているわけではありません。Webアプリを作ったのと同じ会話がそのまま続いています。UIの変更を依頼すればWebビルドが更新され、次にAndroidバンドルを依頼すれば、3週間前にズレて分岐した別ブランチではなく、その同じ最新の状態からコンパイルされます。私がこれまで見てきたほとんどのチームは、後からネイティブを付け加えようとして、毎日出荷されるWebアプリと、リリース前に誰かが追いつかせるのを覚えておかなければならないネイティブラッパーという、2つの離れていくコードベースを維持する羽目になります。その乖離こそが陳腐化の温床であり、単一のビルド履歴はまさにそれを取り除きます。ただしこれは両刃の剣でもあります——最近チャットが雑で急いでいれば、Androidビルドもそれをそのまま引き継ぎます。これは別途の仕上げ工程ではなく、実際にそこにあるものをそのまま直接コンパイルするだけなので、実際には人をごまかしにくくします——「提出前に整えます」という抜け道が存在しないからです。

ストア掲載の準備が整ったら、出荷パスはあなた自身のPlayストアリスティングとあなた自身のApple Developerアカウントに引き継がれます。私たちのものではありません。私たちは、あなたと自分自身の流通の間に立ちたくなかったのです。

次に予定しているもの: iOSおよびmacOSのApp Storeビルド。パッケージング機構自体は基本的に上記と同じ形ですが、Appleの署名と審査パイプラインは独自のプロジェクトであり、早く出すよりも、きちんと動く状態で出すことを優先します。
出荷
共有XLinkedInFacebookRedditQuoraWhatsAppTelegramメール
← すべての投稿