RORK LABEN
TOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しましたTOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しました
記事一覧/開発ツール
開発ツール/2026-06-03上級

Rork製6アプリで分析イベントを型で守る — 共有イベント層の設計メモ

6本のアプリでイベント名がバラつき分析が破綻した経験から、型付きイベントレジストリと薄いラッパーで送信を一元化し、CIで定義の差分を検出する設計を実装コード付きでまとめます。

Rork515analyticsTypeScript8Firebase10architecture6

プレミアム記事

壁紙アプリの一つで「保存ボタンのタップ数」を半年ぶりに見ようとしたとき、グラフがある日を境にゼロに落ちていました。障害ではありません。あるアップデートで wallpaper_save というイベント名を、別の開発作業のついでに save_wallpaper へ書き換えてしまっていたのです。アプリは何事もなく動き、クラッシュも出ず、ただ分析ダッシュボードだけが静かに死んでいました。誰も気づかないまま、二つの名前で半年分のデータが分断されていたわけです。

私は2014年から個人でアプリを開発し、おかげさまで累計5,000万ダウンロードに届きました。現在はRorkを使って6本の壁紙アプリを並行して運用していますが、アプリの数が増えるほど、この「イベント名が静かに腐っていく」問題は深刻になります。同じ「壁紙を保存した」という行為に、アプリごとに少しずつ違う名前が付き、いつの間にか横断分析ができなくなる。ここでは、その問題を型で封じ込めるための共有イベント層の設計を、実際に使っているコードとともに残しておきます。同じように複数アプリを運用されている方に向けた、運用の手引きのつもりです。

なぜイベント名は静かに腐っていくのか

分析イベントが厄介なのは、間違っていても何も壊れないからです。save_btn_tap でも wallpaper_saved でも tap_save でも、logEvent(name, params) に文字列として渡される限り、アプリは正常に動きます。型システムも、リンターも、テストも、文字列の中身までは見てくれません。エラーは半年後、ダッシュボードを開いた人間の目だけが検出します。

6アプリ体制ではこれが指数関数的に悪化します。私の経験では、放置した結果として次の3種類の腐敗が同時に進行していました。第一に表記ゆれで、同じ行為に wallpaper_save / save_wallpaper / img_save の3名が並立していました。第二にプロパティの付け忘れで、あるアプリだけ category プロパティを送っておらず、カテゴリ別の保存数が出せませんでした。第三に型の不一致で、is_premium を文字列 "true" で送るアプリと真偽値 true で送るアプリが混在し、Firebase上で別物として集計されていました。

これらはすべて「文字列とany型で送信できてしまう」ことが根本原因です。であれば、送信経路を型で塞いでしまえばよい、というのがこの設計の出発点です。

型付きイベントレジストリを単一の真実とする

まず、すべてのイベント定義を一つのファイルに集約します。イベント名とそのプロパティの形を型として宣言し、ここに無いイベントは送れないようにします。

// packages/analytics/src/events.ts
// 6アプリで共有する「イベント辞書」。ここが唯一の真実。
 
export const EVENTS = {
  wallpaper_save: {
    category: "string",      // 壁紙のカテゴリID
    wallpaper_id: "string",
    source: "string",        // "detail" | "list" | "widget"
  },
  wallpaper_set_lockscreen: {
    wallpaper_id: "string",
  },
  paywall_view: {
    placement: "string",     // どの画面から来たか
    variant: "string",       // A/Bテストの枝
  },
  subscribe_complete: {
    plan: "string",          // "monthly" | "yearly"
    price_jpy: "number",
  },
} as const;
 
// 各イベントのプロパティ型を EVENTS から自動導出する
type PropType<T> = T extends "string" ? string
  : T extends "number" ? number
  : T extends "boolean" ? boolean
  : never;
 
export type EventName = keyof typeof EVENTS;
 
export type EventProps<E extends EventName> = {
  [K in keyof typeof EVENTS[E]]: PropType<typeof EVENTS[E][K]>;
};

この EVENTS オブジェクトが辞書であり、契約書です。新しいイベントを足したいときは必ずここに行を追加することになり、レビューで一覧として目に入ります。プロパティの型まで宣言してあるので、price_jpy に文字列を渡そうとすればコンパイルが通りません。

宮大工だった私の祖父は、「寸法を最初に決めてしまえば、後はそれを守るだけだ」とよく言っていました。イベントスキーマもこれと同じで、寸法(型)を一箇所で決めておけば、各アプリの実装はそれを守るだけで済みます。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
イベント名のtypoや表記ゆれをコンパイル時に止める型付きレジストリの実装
6アプリで送信処理を1枚のラッパーに集約し、共通プロパティの付け忘れを防ぐ設計
CIでイベント定義の差分を検出し、ダッシュボードが静かに壊れるのを防ぐ仕組み
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

開発ツール2026-07-13
WebViewのpostMessageは投げたら終わり — 相関IDで要求と応答を結ぶブリッジを設計する
WebView と React Native の postMessage は片道通信で、送った処理が成功したのか分かりません。相関IDと応答を組み込んだ要求・応答型ブリッジを、動く TypeScript コードで設計します。
開発ツール2026-05-19
Firebase App Check を Rork に段階的に enforcement する — AdMob 不正検知と Crashlytics を壊さない実運用設計
Firebase App Check を本番投入したいが Crashlytics や AdMob を壊したくない、という個人開発者向けに、Rork から DeviceCheck と Play Integrity を段階的に有効化する設計とロールバック手順をまとめます。
開発ツール2026-04-28
Rork が生成したコードの TypeScript 型エラーが消えない時に試す5つの修正パターン
Rork が出力した React Native コードで TypeScript の型エラーが何度修正しても消えない時に、まず疑うべき5つのパターンと具体的な書き換え方を、実例とともにまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →