Hyunjun Kim

Momento

AIに指示して同じアプリをiOSとAndroidの両方でネイティブ開発 — カップルの思い出を自動でまとめるアプリ

テスト中アイデア→リリース約7〜8週間

2026.05 – 2026.06 / 1人(AIをチームとして活用) / iOS · Android

課題
2人の思い出を毎回手作業で記録するのは面倒 — 2人が一緒にいることをアプリに気づかせたい。
担当
企画 · 基準設定 · AIへの開発指示(iOS、Android、バックエンド)
使用技術
SwiftUI · Kotlin · Jetpack Compose · Supabase · WidgetKit

成果

開発開始 → TestFlight(iOS・Android ネイティブ)
約7〜8週間
開発開始 → TestFlight(iOS・Android ネイティブ)
iOSとAndroidでそれぞれネイティブ開発
2プラットフォーム
iOSとAndroidでそれぞれネイティブ開発
iOSの機能モジュール
24
iOSの機能モジュール
iOS版をアップロード済み(Android版は開発中)
TestFlight
iOS版をアップロード済み(Android版は開発中)

⚡ アイデア→リリース

約7〜8週間

  1. 2026-03-21

    最初の指示

  2. +45 days

    2026-05-05

    最初の動作ビルド

  3. +45 days

    2026-06-19

    初回リリース · 最新

開発開始(04-27)→ TestFlight まで約7〜8週間(実作業 約23日)。アイデアから開発開始まで約5週間の空白(他のプロジェクトと並行)

01

アイデア・課題

最初の指示:「カップル2人がほぼ同じ場所(誤差10m程度)にいるときにどちらかが写真を撮ったら、その写真を日付・位置と一緒に自動で集める — これってできる?」 原文(韓国語):「커플 둘이 비슷한 공간(오차 10m)에 같이 있을 때 한 명이 사진을 찍으면, 그 사진을 날짜·위치와 함께 자동으로 모아주기 — 할 수 있나?」

2人で過ごした瞬間を毎回手作業で記録するのは面倒です。2人が同じ時間に同じ場所にいることをアプリ自身が察知し、それを1つの思い出としてまとめてくれたら — という日常の発想から生まれました。

02

企画と基準

  • 機能範囲を自分で企画:ペアリング、タイムライン、日記、記念日、地図、位置チェックイン
  • プラットフォームの基準:iOSはSwiftUI、AndroidはKotlin/Composeで、それぞれネイティブ開発。**「iOSのコードをAndroidに移植しない — 各プラットフォームの慣習に従う」**を絶対ルールにしました。
  • デザインの基準:「デコ(手帳デコ)」風のスクラップブックのトーン(コーラル #E07A5F、ポラロイド/マスキングテープ/手書き文字)
  • AI作業の安全ルール:どんな変更も、副作用を説明させて承認を取ってから
Momento — momento 02 1
Momento — momento 02 2
Momento — momento 02 3
Momento — momento 04 ios
iOS · SwiftUI
Momento — momento 04 android
Android · Jetpack Compose

03

AIへの指示プロセス

Fig. momento-03

AIへの指示プロセス

  1. 01 最初の指示

    iOSとAndroidそれぞれで、同じ機能を各プラットフォームのやり方で作らせる。

  2. 02 確認したこと

    ビルドと画面を実際に動かし、サーバーの日付で表示が崩れる箇所や、Androidのビルドが止まる箇所を見つけました。

  3. 03 修正

    原因を指摘して指示しました —「サーバーのさまざまな日付形式を柔軟に受け付けるデコーダーを作って」「AndroidのDIツールが合わないので、手動のシングルトンに切り替えて」。

実際の指示(抜粋)

  • Androidでは iOS のコードをコピーしないで、プラットフォームのやり方で作り直して。Original안드로이드는 iOS 코드를 복사하지 말고 그 플랫폼 관례대로 다시 만들어.
  • できたと記憶で答えないで、実際のコードを確認して見せて。Original됐다는 걸 기억 말고 실제 코드로 확인해서 보여줘.

04

つまずいた点と解決方法

  • Supabase の日付形式の不一致:サーバーの日付形式が統一されておらず、iOSのデコードが失敗していました。複数の形式を受け付けるカスタムデコーダーを作るようAIに指示しました。
  • AndroidのDIツールの非互換:Hilt が最新のビルド構成と衝突したため、手動シングルトンへの切り替えを指示してビルドを安定させました。
  • 位置マッチングの信頼性:端末上で位置を比較すると、機種によって結果がばらつき、バッテリーも消耗しました。そこで、位置情報(ping)をサーバーに集め、SQL関数でマッチング候補を計算する設計に変更しました。

Fig. momento-07

位置マッチングを端末からサーバーへ移した設計

端末 ↔ 端末で直接比較サーバーで計算
iOSAの位置記録(ping)
AndroidBの位置記録(ping)
DB位置記録をサーバーに保存
SQLマッチング関数同じ場所・時間の候補を計算
結果思い出を自動作成2人のタイムラインに
Comparing locations app-to-app gave inconsistent results and drained battery, so pings now go to the server and a SQL function computes match candidates.

Case 01

サーバーから受け取った日付がiOSでデコードできず、画面が崩れた。

  1. 症状

    サーバーから受け取った日付がiOSでデコードできず、画面が崩れた。

  2. AIへの説明

    サーバーの日付形式が統一されていないため、パースに失敗している」と事実として伝えた。Original서버 날짜 형식이 일정치 않아 파싱이 실패한다"고 사실로 전달.
  3. AIの最初の試み

    単一の形式を前提とした修正は、他の形式で失敗した。

  4. 自分が気づいた点

    複数の形式を受け付ける柔軟なデコーダーが必要だった。

  5. 解決

    カスタムデコーダー(複数形式に対応)の実装を指示。

  6. 再発防止

    外部から来る値は「形式が変わりうる」ものとして扱い、防御的にパースする。

Case 02

DIツール(Hilt)と最新のビルド構成が衝突し、Androidのビルドが失敗した。

  1. 症状

    DIツール(Hilt)と最新のビルド構成が衝突し、Androidのビルドが失敗した。

  2. AIへの説明

    ビルドログと一緒に症状を共有した。Original빌드 로그와 함께 증상 전달.
  3. AIの最初の試み

    バージョンの変更だけでは解決しなかった。

  4. 自分が気づいた点

    Hilt ではなく手動シングルトンで回避するのが正しい判断だった。

  5. 解決

    手動シングルトンへの切り替えを指示し、ビルドを安定させた。

  6. 再発防止

    互換性のないツールを無理に使わず、まず代替案を比較する。

05

成果

  • 同じアプリを iOS(SwiftUI)と Android(Compose)の両方でネイティブ開発
  • iOS:Swiftファイル136個、約17,911行/機能モジュール24個、Android:Kotlinファイル84個、約11,454行
  • iOS版を TestFlight にアップロード(App Store の支払い用銀行口座・税務フォームの登録を含む)。Android版は開発中
Momento — momento 06

06

振り返り

同じ機能を2通りに指示してみて、それがコピー&ペーストではないことを学びました。プラットフォームごとに自然な設計があり、AIへの指示でもそれを切り分ける必要があります。次は、バックエンドと共通ルールを先に固めてから、両方のクライアントをつなぎます。

(01) Review

Honest Review

開発者が作っていたら?

強み3
  • 機能範囲 — iOSの機能モジュール24個、TestFlight配信中

    ペアリング、位置マッチング、タイムライン、地図、日記、記念日、アプリ内課金、広告、ウィジェット、アカウント復旧。TestFlight ビルド12。

  • スピードとコスト — 2つのネイティブアプリで約29K行を約7週間で

    iOS(SwiftUI)とAndroid(Compose)を、14回のデータベースマイグレーションを経た1つのバックエンド上でそれぞれ開発。

  • 多言語対応 — 4言語、両プラットフォームで同じ約220キー

    英語・韓国語・日本語・タイ語を、iOSとAndroidで同一に維持。

同等4
  • アーキテクチャ — 機能単位の構成、各プラットフォーム標準のパターン

    機能別フォルダ、@Observable+13個のViewModel、ほとんどの画面が300〜500行。バックエンドのヘルパーを共有。

  • コードの健全性 — クリーン

    強制アンラップやクラッシュしやすいキャストはほぼなし。1,000行を超えるファイルもなし。

  • パフォーマンス — バッテリーに配慮した位置情報取得

    iOSは100mの移動フィルター、Androidは15分間隔のバックグラウンド処理、データベースには空間インデックス。

  • セキュリティの基本 — 全テーブルにアクセスルール

    全22テーブルに行レベルのアクセスルール(ポリシー47個)。キーはサーバー側で管理。

次のステップ(改善中)5
  • テストと自動化 — テストはマッチングエンジンのみ

    マッチング用のバックエンドテストが8件。アプリのテストとCIはなし。

    改善計画 → ペアリング・マッチング・購入フローのテストと、両アプリのCI。

  • リリースと運用 — 本番データベースとリポジトリに差分が発生

    バックエンドのリポジトリは5月初めで更新が止まり、本番データベースだけが変更され続けました。

    改善計画 → 本番スキーマをマイグレーションファイルに書き出してコミットし、ダッシュボードだけでの変更をやめる。

  • セキュリティ — ストア公開前に強化予定

    ストア公開前に購入のサーバー側チェックを追加し、エラーは握りつぶさず表に出すようにします。

    改善計画 → サーバー側の購入検証と、適切なエラーレポート。

  • Androidの完成度 — AndroidはiOSより遅れている

    iOSを先に完成させ、Androidは開発中です。

    改善計画 → コードのコピーではなく、iOSの機能一覧をもとにAndroidを同等の水準に引き上げる。

  • アクセシビリティ — ラベルは主要画面のみ

    スクリーンリーダー用ラベルはiOSで23箇所、Androidで約10箇所。

    改善計画 → ラベルと文字サイズの拡大対応をリリースチェックリストの項目にする。

次のプロジェクト →

AttenNFC

企画者の設計をAIで実装 — タイの小規模事業者向け、NFC+GPS勤怠管理と給与の自動計算

01 NFC動的トークン
02 Wi-Fi信号(補助)
03 端末バインディング
04 root化・脱獄の検知
出退勤の記録
ケーススタディを見る
履歴書 PDF(英語)