私は個人でアプリ開発をしていて、2014年からこの仕事を続けています。これまでに公開してきたアプリの中には、10年以上運用を続けているものもあれば、数年で市場から消えたものもあります。Rork で作ったアプリはまだ2年ほどの運用ですが、それでも「アプリが老いる」という現象は確実に現れてきています。
この記事は、短期的なリリースノウハウではなく、数年単位でアプリを運用し続ける個人開発者の目線 で、Rork アプリの保守設計について書きます。個人開発では、作る時間より運用している時間の方がずっと長いので、このテーマは軽視できません。
アプリは2年目から確実に「老ける」
Rork で作ったアプリをリリースした直後は、全てが新しく、コードも綺麗で、挙動も想定通りです。ここで多くの個人開発者(過去の私も含めて)が誤解するのは、この状態がデフォルトである と思い込むことです。
実際には、アプリは明日から老化を始めます。主な老化要因はこの5つです。
- iOS / Android OS のメジャー更新: 毎年1回必ず来ます。多くは後方互換ですが、権限モデルや通知仕様は頻繁に変わります
- SDK・ライブラリの破壊的変更: AdMob、RevenueCat、Firebase、Supabase のいずれも年に数回の破壊的変更があります
- ユーザー端末の世代交代: リリース時に想定した画面サイズや性能範囲が、1〜2年で大きく変わります
- 審査ポリシーの更新: App Store Review Guidelines、Google Play Policy ともに年に5〜6回の実質的な更新があります
- 自分自身の記憶の劣化: 1年前に書いたコードは他人のコードと変わらない、というのは真実です
この5つは、リリース直後のアプリに対しては目に見えません。見えるようになる頃には、すでに対応の選択肢が減っています。だからリリース時点でこれらに備える仕込みが必要 です。
仕込み1 — 「何が動いているか」を自分に伝える観測ポイント
長期運用で一番困るのは、「アプリが壊れているかどうかも分からない」状態です。個人開発では、ユーザーからのレビューで初めて障害に気づくことが多いですが、その時点で既に遅いです。
Rork アプリで私が最低限入れている観測は以下です。
- アプリ起動成功率: クラッシュレポートツール(Crashlytics、Sentry)で、起動完了イベントと起動トリガーの比率を計測
- 主要機能の完了率: 購入、登録、メイン画面の表示完了など、アプリの存在意義に直結する処理の成功率
- 広告表示率: AdMob の
onAdShowedFullScreenContentコールバックの発火率を独自ロギング
3つ目は重要です。広告が表示されなくなっていても、ユーザーからのクレームはほとんど来ません。収益だけが静かに落ちていきます。これは観測していないと気づけません。
私は過去に、Rork アプリの広告実装に半年気づかないバグを仕込んだことがあります。onLoaded は呼ばれるのに onShowed が呼ばれない、という状態で、ユーザー体験上は「広告が出ない快適なアプリ」でした。収益レポートを見て初めて異常に気づきました。
仕込み2 — 外部依存を疎結合にしておく
長期運用で確実に起きるのが、外部サービスの仕様変更、値上げ、サービス終了です。個人開発者にとって、この変化に即応するのは体力的に厳しいので、最初から依存先を差し替え可能な構造にしておく のが現実解です。
Rork アプリでの私の設計指針はこうです。
- 決済は必ず抽象層を挟む: RevenueCat、StoreKit 2 いずれも、アプリ内の利用側から見て同じインターフェースに見えるよう、薄い抽象層を作る
- 広告 SDK は1箇所でのみ初期化する: AdMob の初期化ロジックを1ファイルに集約します。2年後に AdMob から別 SDK に乗り換える可能性を常に意識する
- アナリティクスは複数持つ: Firebase Analytics と別のサービスを並行させる。片方が値上げまたは廃止されても継続できる
「やりすぎでは?」と思うかもしれませんが、これは過去10年間で実際に起きたことへの備えです。一つだけ例を挙げると、私が使っていた某プッシュ通知サービスは、ある日突然無料枠を大幅縮小しました。疎結合にしていれば週末で対応できますが、密結合だと数週間の改修作業になります。
仕込み3 — 自分自身への引き継ぎ資料を書く
個人開発で最も過小評価されているのが、未来の自分への引き継ぎ資料 です。1年後の自分は、今の自分と同じくらい丁寧な他人です。
Rork アプリの場合、私は以下の文書をリポジトリに必ず残します。
- README.md: 起動手順、依存環境、よく使うコマンド
- docs/operation.md: リリース手順、審査提出時の注意点、リジェクト時の対応ログ
- docs/known-issues.md: 既知の不具合と対処法、保留中の改善案
- docs/decision-log.md: なぜこの技術を選んだか、当時の代替案、再検討する条件
4つ目が特に効きます。2年後の自分が「なぜこれ使ってるんだっけ」と悩む時間を、過去の自分が残したメモが救います。
延命と廃止の分かれ目
長期運用のアプリには必ず、「もう手放したほうがいい」タイミングが来ます。この判断基準を言語化しておかないと、惰性で維持費だけ払い続ける状態になります。
私が使っている判断軸はこの4つです。
- 月次の運用工数 vs 月次収益: 工数 × 自分の時給 が収益を上回っているか
- 技術的負債の累積度: OS 新バージョンへの対応が数週間かかる状態なら危険信号
- ユーザーの使用頻度: DAU / MAU の比率と、絶対数の推移
- 自分自身の愛着: これが一番大事です
4つ目を軽んじる個人開発者が多いですが、個人開発では「愛着があるアプリを続ける」ことが長期のモチベーションに直結します。逆に愛着が残っていて1〜3 が少し赤でも、畳むべきではないことが多いです。数字だけで機械的に判断すると、自分のアプリ開発者としての生命線を削ってしまいます。
一方、愛着も数字も枯れているアプリは、機能停止ではなく、ストア上からの Sunset で扱います。既存ユーザーへの通知、代替案の提示、データエクスポート手段の提供を、最低3ヶ月前から準備します。
2年目以降の Rork アプリで私がやっていること
具体的に、2年目以降の Rork アプリで私が毎月行っている保守タスクはこんな感じです。
- 月初: 前月のクラッシュ、広告表示率、購入成功率のレビュー
- 月中: iOS/Android OS の最新ベータで主要機能の動作確認
- 月末: 依存ライブラリの脆弱性チェックと更新
これ以上は個人開発では回りません。逆に、これを省略すると1年後に大きな負債として返ってきます。私の経験則では、月に4〜6時間の保守時間 を1アプリあたりに割り当てるのが、持続可能なラインです。
長く運用してわかる本当の価値
10年以上アプリを運用していて、私が実感するのは、作ったアプリとの関係は、リリースの瞬間ではなく、その後の数年で深まる ということです。
最初は「作りたいものを作った」アプリでも、ユーザーの反応、市場の変化、自分の成長を通じて、少しずつ違う姿に育っていきます。Rork で作るアプリも、3年後には今とは違う顔をしているはずです。そのときに後悔のない保守設計を、最初から仕込んでおけるのは、自分自身への親切だと思います。
長く続けるつもりがあるなら、リリース直後の今日、この記事の「仕込み1〜3」のうち1つでも始めてみてください。1年後の自分が、間違いなく感謝します。