モバイルアプリの実務
この部の 9 / 9 章 ・ 全体で 42 / 76 章 ・ 読了目安 45 分
- 後方互換性と冪等性が必須になる理由を説明できる
- 端末を信頼しない設計ができる
- API を作る側としてモバイルの前提を考慮できる
Web とモバイルアプリは、同じ「クライアント」でも運用の前提が根本的に違います。
Web: 直せばすぐ全員に反映される
モバイル: 審査を通し、利用者が更新して、初めて反映される
この違いが、設計のあらゆる部分に影響します。 モバイルを担当しなくても、API を作る側は必ず知っておく必要があります。
最大の違い: 配ったものを取り消せない
1. コードを直す
2. ストアに提出する
3. 審査を待つ(数時間〜数日。リジェクトされることもある)
4. 公開される
5. 利用者が更新する ← ここが最大の問題
5 が保証されません。 自動更新を切っている人、容量が足りない人、 古い OS のままの人がいます。
つまり、
今この瞬間、あなたのサーバーには
v1.0 / v1.4 / v2.0 / v2.3 のアプリからリクエストが来ている
これが、モバイルを持つサービスの API 設計を決定づけます。
□ API の後方互換性は「望ましい」ではなく「必須」(スキーマと RPC)
□ フィールドを消せない。型を変えられない
□ 「フロントと同時にデプロイすればいい」が通用しない
□ 半年前のバージョンをいつまでサポートするかを、方針として決める
Web だけの経験しかないと、ここで必ず事故ります。
強制アップデートの仕組みを最初から入れる
アプリ起動時にサーバーへ問い合わせ
→ 「このバージョンは最低要件を満たしていますか」
→ 満たしていなければ、更新を促す画面を出して先に進ませない
これを後から入れることはできません(入れる前のバージョンには届かないため)。 初回リリースに必ず含めてください。モバイル開発で最も重要な初期設計の1つです。
ネイティブか、クロスプラットフォームか
| 方式 | 特徴 |
|---|---|
| ネイティブ(Swift / Kotlin) | OS の機能をすべて使える。2つ作る必要がある |
| クロスプラットフォーム(Flutter / React Native) | 1つのコードで両方。OS 固有機能は追加実装が要る |
| Web View 中心 | Web の資産を活かせる。体験は劣ることが多い |
どれが正しいということはありません(新しい言語をどう学ぶか)。 チームの人数、求める体験、OS 固有機能の必要性で決まります。
新人として重要なのは、なぜその選択をしているかを聞くことです。
ライフサイクル — アプリは止まったり殺されたりする
Web のタブとは違い、モバイルアプリはOS に管理されています。
起動 → 前面(動作中) → 背面(バックグラウンド) → OS に破棄される
↑ ここで処理が止まる
□ バックグラウンドでは、通信も処理も制限される(OS が止める)
□ メモリが足りなければ、アプリは予告なく破棄される
□ 復帰時、画面の状態を自分で復元する必要がある
入力途中でホーム画面に戻り、しばらくして戻ってきたらアプリが破棄されていた。
これはバグではなく、OS の正常な動作です。
□ 入力中の内容は、こまめにローカルへ保存する
□ 復帰時に「前回の続きから」を復元する
□ 長いフォームは、途中保存を前提に設計する
Web でも同じ配慮は要りますが、モバイルでは頻度が桁違いです。
ネットワークは、繋がらないもの
Web: 基本的に繋がっている前提で書ける
モバイル: 電車・地下・エレベーター・機内モード・回線切り替え
□ オフラインでも、できることは動かす(閲覧・下書き)
□ 失敗したら、後で自動的に再送する(非同期処理とメッセージングの冪等性が必須)
□ 通信中であることを必ず表示する
□ タイムアウトを短めにし、再試行の導線を出す
□ 大きな通信は Wi-Fi 時に限定することも検討する
送信 → タイムアウト → 利用者が再送 → 実は1回目も届いていた
→ 二重に注文が作られる
モバイルは電波状況で「送ったか分からない」状態が頻繁に起きます。
だから、冪等キー(API を設計する・非同期処理とメッセージング)が Web 以上に重要です。 「モバイルアプリがあるサービスの API は、冪等でなければならない」 と考えてください。
端末に何を保存してよいか
端末は、利用者の手元にあります。 解析される前提で考えます。
□ 認証トークン → Keychain(iOS)/ Keystore(Android)などの安全な領域へ
□ 個人情報 → 必要最小限。可能なら保存しない(エンジニアと法律)
□ APIキー等 → アプリに埋め込んだ時点で公開情報。解析すれば取り出せる
□ 業務ロジック → 金額計算や権限判定を端末側で完結させない(認証と認可の実装)
「アプリの中だから見えない」は成立しません。 これはフロントエンドの環境変数(フロントエンドの実務)と同じ話です。
権限
カメラ・位置情報・通知・連絡先などは、利用者が拒否できます。
□ 拒否された場合の画面を必ず作る
□ 「なぜ必要か」を、要求する直前に説明する(許可率が大きく変わる)
□ 起動直後にすべての権限を求めない(拒否されやすい)
□ 一度拒否されたら、アプリからは再要求できない(設定アプリへ誘導する)
プッシュ通知
□ 許可を取る必要がある(拒否される前提)
□ 端末トークンは変わる。サーバー側で更新を受け付ける
□ **届く保証はない**。重要な情報を通知だけに頼らない
□ 送りすぎると通知を切られる。切られたら二度と届かない
通知は「届いたらラッキー」な経路です。 重要な連絡は、アプリ内にも必ず残してください。
ストア課金
自社の決済ではなく、ストアの仕組みを使う必要がある場合があります (デジタルコンテンツの販売など。規約は変化するので必ず最新を確認してください)。
□ ストアの手数料がかかる
□ レシートの検証は必ずサーバー側で行う(端末の言い分を信じない)
□ サブスクリプションは状態管理が複雑(更新・解約・返金・猶予期間)
□ 課金の状態は、サーバー側を正本にする
端末の言い分だけで課金状態を有効にすると、改造したアプリから無料で使えます。
必ず、ストアのサーバーに問い合わせて検証してください。 認証と認可の実装の「クライアントを信頼しない」と同じ原則です。
リリースの運用
Web と比べて、やり直しが効かないぶん慎重になります。
□ 段階的リリース(数%から始めて、問題が無ければ拡大する)
□ **フィーチャーフラグ**(CI/CD)— アプリを更新せずに機能を止められる
□ クラッシュ収集を必ず入れる(Crashlytics 等)
□ リリース後の数値を見る(クラッシュ率、起動時間、離脱)
Web なら、問題があればすぐ切り戻せます(CI/CD)。
モバイルでは切り戻せません。審査からやり直しです。
だから、サーバー側から機能をオフにできる仕組みを持っておきます。
問題発覚 → サーバーの設定を変更 → 全ユーザーで機能が無効になる(数分)
これが無いと、「審査を通すまでの数日間、障害が続く」ことになります。
端末と OS の多様性
□ 画面サイズ・解像度・ノッチ・折りたたみ
□ OS のバージョン(サポート範囲をチームで決める)
□ 端末の性能差(低スペック端末で動くか)
□ 地域・言語・文字サイズ設定(アクセシビリティ)
実機で確認するしかありません。シミュレータだけでは分からない差があります。
API を作る側が知っておくべきこと
モバイル担当でなくても、サーバー側の設計が変わります。
□ 後方互換性は必須(古いバージョンが動き続ける)
□ 冪等性は必須(電波状況で再送が起きる)
□ 通信回数を減らす設計(1画面に必要なデータをまとめて返す)
□ ペイロードを小さく(モバイル回線と電池を消費する)
□ バージョン情報を受け取り、最低要件を返せるようにする
□ 「どのバージョンが、どれだけ使われているか」を計測する
モバイルアプリを持つサービスの API から、使われていないフィールドを削除したいと考えています。
実務の落とし穴まとめ
- 強制アップデートの仕組みを入れずにリリース — 後から追加できない
- API のフィールドを削除・型変更 — 古いアプリが壊れる
- 冪等性が無い — 電波状況による再送で二重登録
- アプリ破棄を考慮しない — 入力が消える
- オフラインを考えない — 圏外で何もできなくなる
- 端末に秘密情報を埋め込む — 解析すれば取り出せる
- 権限を拒否された場合の画面が無い — 詰む
- 通知に依存する — 届かない前提で設計する
- 端末の「購入しました」を信じる — サーバーで検証する
- フィーチャーフラグが無い — 問題が起きても審査待ちになる
- API の往復が多い — モバイル回線では体感が桁違いに悪い
まとめ
- モバイルの本質は配ったものを取り消せないこと。 だから複数バージョンが同時に動き続ける
- API の後方互換性と冪等性は必須。Web の常識が通用しない
- 強制アップデートの仕組みは初回リリースに含める
- アプリはOS に破棄される。状態の保存と復元を前提にする
- ネットワークは繋がらないもの。オフラインと再送を設計する
- 端末に置いたものは解析される。判定はサーバー側で
- 権限も通知も拒否・不達が前提
- フィーチャーフラグが Web 以上に重要。切り戻せないから
- API を作る側も、この前提を知っている必要がある
公式ドキュメント
迷ったら一次情報に戻ってください。
| 対象 | リンク |
|---|---|
| Apple Developer Documentation | https://developer.apple.com/documentation/ |
| Android Developers(日本語) | https://developer.android.com/?hl=ja |
| App Store Review ガイドライン(日本語) | https://developer.apple.com/jp/app-store/review/guidelines/ |
| Google Play デベロッパー ポリシー | https://play.google.com/about/developer-content-policy/ |
| Flutter | https://docs.flutter.dev/ |
章末問題
モバイルアプリから注文を送信する API を設計します。Web 版と比べて、特に重要になるのはどれですか。
第4部はここまでです。次の第5部では、 これらのクライアントが呼ぶサーバー側を作っていきます。