Momento กำกับ AI ให้สร้างแอปเดียวกันแบบเนทีฟทั้งบน iOS และ Android — แอปเก็บความทรงจำของคู่รักที่จับคู่ช่วงเวลาให้อัตโนมัติ
กำลังทดสอบ ⚡ ไอเดีย→เปิดตัว ~7–8 สัปดาห์
2026.05 – 2026.06 / คนเดียว (AI เป็นทีม) / iOS · Android
ปัญหา การบันทึกทุกช่วงเวลาร่วมกันด้วยมือเป็นเรื่องน่าเบื่อ — ให้แอปรู้เองว่าคู่รักอยู่ด้วยกัน
บทบาทของผม วางแผน · กำหนดมาตรฐาน · กำกับ 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 สัปดาห์
+45 days
2026-05-05
บิลด์แรกที่ใช้งานได้
+45 days
2026-06-19
เปิดตัวครั้งแรก · ล่าสุด
2026-03-21
คำสั่งแรก
+45 days 2026-05-05
บิลด์แรกที่ใช้งานได้
+45 days 2026-06-19
เปิดตัวครั้งแรก · ล่าสุด
จากเริ่มพัฒนา (04-27) สู่ TestFlight ~7–8 สัปดาห์ (ทำงานจริง ~23 วัน) · ช่วงห่างระหว่างไอเดียกับการเริ่มพัฒนา ~5 สัปดาห์ (ทำโปรเจกต์อื่นคู่ขนาน)
คำสั่งแรก: "เวลาคู่รักอยู่ในที่ใกล้ ๆ กัน (ระยะคลาดเคลื่อน ~10m) แล้วคนใดคนหนึ่งถ่ายรูป ให้รวบรวมรูปนั้นพร้อมวันที่และสถานที่ให้อัตโนมัติ — ทำได้ไหม?"
ต้นฉบับ (KO): "커플 둘이 비슷한 공간(오차 10m)에 같이 있을 때 한 명이 사진을 찍으면, 그 사진을 날짜·위치와 함께 자동으로 모아주기 — 할 수 있나?"
การบันทึกทุกช่วงเวลาร่วมกันด้วยมือเป็นเรื่องน่าเบื่อ ไอเดียนี้มาจากชีวิตประจำวัน: จะเป็นอย่างไรถ้าแอปรู้เองว่าสองคนอยู่ที่เดียวกันในเวลาเดียวกัน แล้วรวบรวมเป็นความทรงจำให้
02
แผนและมาตรฐานที่ผมกำหนด
วางแผนขอบเขตฟีเจอร์เอง: การจับคู่บัญชีคู่รัก ไทม์ไลน์ ไดอารี่ วันครบรอบ แผนที่ การเช็กอินตำแหน่ง
มาตรฐานแพลตฟอร์ม: iOS ใช้ SwiftUI, Android ใช้ Kotlin/Compose แบบ เนทีฟ ทั้งคู่ ผมตั้งเป็นกฎเด็ดขาด: "อย่ายกโค้ด iOS ไปใส่ Android — ให้ทำตามแนวปฏิบัติของแต่ละแพลตฟอร์ม"
มาตรฐานดีไซน์: โทนสมุดสแครปบุ๊กแบบ "dakku" (สีคอรัล #E07A5F, ภาพโพลารอยด์ / เทปกาวลวดลาย / ลายมือ)
กฎความปลอดภัยสำหรับการทำงานกับ AI: อธิบายผลกระทบข้างเคียงและขออนุมัติก่อนแก้ทุกครั้ง
iOS · SwiftUI Android · Jetpack Compose Fig. momento-03
การกำกับ AI
01 คำสั่งแรก
สร้างฟีเจอร์เดียวกันบน iOS และ Android ตามแบบของแต่ละแพลตฟอร์ม
02 สิ่งที่ผมตรวจ
ผมรันบิลด์และหน้าจอ และพบจุดที่วันที่จากเซิร์ฟเวอร์ทำให้พัง และจุดที่บิลด์ Android ค้าง
03 การแก้ไข
ผมสั่งงานโดยชี้ไปที่สาเหตุ — "สร้าง decoder ที่รับรูปแบบวันที่หลากหลายจากเซิร์ฟเวอร์ได้อย่างยืดหยุ่น" "เครื่องมือ DI ของ Android ไม่เข้ากัน ให้เปลี่ยนไปใช้ singleton แบบเขียนเอง"
คำสั่งจริง (ตัดตอน)
› บน Android อย่าคัดลอกโค้ด iOS — สร้างใหม่ตามแบบของแพลตฟอร์มนั้นเองOriginal 안드로이드는 iOS 코드를 복사하지 말고 그 플랫폼 관례대로 다시 만들어.› อย่าบอกว่าเสร็จจากความจำ — ตรวจโค้ดจริงแล้วแสดงให้ดูOriginal 됐다는 걸 기억 말고 실제 코드로 확인해서 보여줘.
รูปแบบวันที่ของ Supabase ไม่ตรงกัน : รูปแบบวันที่จากเซิร์ฟเวอร์ไม่สม่ำเสมอ ทำให้การ decode บน iOS พัง ผมกำกับ AI ให้สร้าง decoder เฉพาะที่รับได้หลายรูปแบบ
เครื่องมือ DI ของ Android ไม่เข้ากัน : Hilt ขัดกับการตั้งค่าบิลด์เวอร์ชันล่าสุด ผมจึงกำกับให้เปลี่ยนไปใช้ singleton แบบเขียนเองเพื่อให้บิลด์เสถียร
ความน่าเชื่อถือของการจับคู่ตำแหน่ง : การเทียบตำแหน่งบนอุปกรณ์ให้ผลต่างกันไปตามรุ่นมือถือและกินแบตเตอรี่ ผมเปลี่ยนการออกแบบให้รวบรวมสัญญาณตำแหน่ง (ping) ไว้บนเซิร์ฟเวอร์ และคำนวณผู้ที่น่าจะตรงกันด้วยฟังก์ชัน SQL
Fig. momento-07
ย้ายการจับคู่ตำแหน่งจากอุปกรณ์ไปไว้บนเซิร์ฟเวอร์
เทียบระหว่างอุปกรณ์ ↔ อุปกรณ์ → คำนวณบนเซิร์ฟเวอร์
iOS ping ตำแหน่งของ A
Android ping ตำแหน่งของ B
DB เก็บ ping ไว้บนเซิร์ฟเวอร์
SQL ฟังก์ชันจับคู่ หาผู้ที่อยู่ที่เดียวกันในเวลาเดียวกัน
ผลลัพธ์ สร้างความทรงจำ บนไทม์ไลน์ของทั้งสองคน
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
วันที่จากเซิร์ฟเวอร์ decode บน iOS ไม่สำเร็จ … ! อาการ
วันที่จากเซิร์ฟเวอร์ decode บน iOS ไม่สำเร็จ ทำให้หน้าจอพัง
› สิ่งที่ผมบอก AI
รูปแบบวันที่จากเซิร์ฟเวอร์ไม่สม่ำเสมอ การ parse จึงล้มเหลว" ในฐานะข้อเท็จจริงOriginal 서버 날짜 형식이 일정치 않아 파싱이 실패한다"고 사실로 전달. ↺ ความพยายามแรกของ AI
การแก้ที่สมมติว่ามีรูปแบบเดียว ล้มเหลวกับรูปแบบอื่น
◎ จุดที่ผมจับได้
ต้องมี decoder ที่ยืดหยุ่นและรับได้หลายรูปแบบ
✓ วิธีแก้
กำกับให้สร้าง decoder เฉพาะ (รับได้หลายรูปแบบ)
⟲ การป้องกันไม่ให้เกิดซ้ำ
ผมถือว่าค่าที่มาจากภายนอก "รูปแบบอาจเปลี่ยนได้" และ parse อย่างระมัดระวัง
Case 02
บิลด์ Android ล้มเหลวจากความขัดกันระหว่างเครื… ! อาการ
บิลด์ Android ล้มเหลวจากความขัดกันระหว่างเครื่องมือ DI (Hilt) กับการตั้งค่าบิลด์เวอร์ชันล่าสุด
› สิ่งที่ผมบอก AI
แชร์อาการพร้อม build logOriginal 빌드 로그와 함께 증상 전달. ↺ ความพยายามแรกของ AI
การเปลี่ยนเวอร์ชันอย่างเดียวแก้ไม่ได้
◎ จุดที่ผมจับได้
การเลี่ยงไปใช้ singleton แบบเขียนเองแทน Hilt คือทางที่ถูก
✓ วิธีแก้
กำกับให้เปลี่ยนไปใช้ singleton แบบเขียนเอง ทำให้บิลด์เสถียร
⟲ การป้องกันไม่ให้เกิดซ้ำ
ผมไม่ฝืนใช้เครื่องมือที่ไม่เข้ากัน — ชั่งน้ำหนักทางเลือกอื่นก่อน
สร้างแอปเดียวกัน แบบเนทีฟทั้งบน iOS (SwiftUI) และ Android (Compose)
iOS: ไฟล์ Swift 136 ไฟล์ ~17,911 บรรทัด / 24 โมดูลฟีเจอร์ · Android: ไฟล์ Kotlin 84 ไฟล์ ~11,454 บรรทัด
iOS อัปโหลดขึ้น TestFlight แล้ว (รวมถึงบัญชีธนาคารรับเงินและแบบฟอร์มภาษีของ App Store) · Android กำลังพัฒนา
การสั่งฟีเจอร์เดียวกันในสองแบบสอนผมว่ามันไม่ใช่การคัดลอกวาง — แต่ละแพลตฟอร์มมีการออกแบบที่เป็นธรรมชาติของตัวเอง และผมต้องแยกเรื่องนี้ให้ชัดในวิธีที่กำกับ AI ครั้งหน้าผมจะล็อกแบ็กเอนด์และกฎร่วมให้เสร็จก่อน แล้วค่อยต่อไคลเอนต์ทั้งสองฝั่ง
(01) Review
Honest รีวิว ถ้านักพัฒนาเป็นคนสร้าง
● จุดแข็ง3
ขอบเขตฟีเจอร์ — iOS 24 โมดูลฟีเจอร์ อยู่บน TestFlight
การจับคู่บัญชีคู่รัก การจับคู่ตำแหน่ง ไทม์ไลน์ แผนที่ ไดอารี่ วันครบรอบ การซื้อในแอป โฆษณา วิดเจ็ต การกู้คืนบัญชี · TestFlight บิลด์ที่ 12
ความเร็วและต้นทุน — ~29K บรรทัด แอปเนทีฟ 2 ตัว ใน ~7 สัปดาห์
iOS (SwiftUI) และ Android (Compose) สร้างแยกกันบนแบ็กเอนด์เดียว พร้อม migration ฐานข้อมูล 14 ชุด
การรองรับหลายภาษา — 4 ภาษา คีย์ ~220 ชุดเดียวกันทั้งสองแพลตฟอร์ม
อังกฤษ เกาหลี ญี่ปุ่น ไทย เหมือนกันทั้ง iOS และ Android
◐ เทียบเท่า4
สถาปัตยกรรม — แบ่งตามฟีเจอร์ ใช้แพตเทิร์นมาตรฐานของแต่ละแพลตฟอร์ม
โฟลเดอร์แยกตามฟีเจอร์ @Observable + view model 13 ตัว หน้าจอส่วนใหญ่ยาว 300–500 บรรทัด และมี helper ฝั่งแบ็กเอนด์ใช้ร่วมกัน
ความสะอาดของโค้ด — สะอาด
แทบไม่มี force-unwrap หรือการ cast ที่เสี่ยงแครช และไม่มีไฟล์ใดยาวเกิน 1,000 บรรทัด
ประสิทธิภาพ — ระบบตำแหน่งที่คำนึงถึงแบตเตอรี่
ตัวกรองการเคลื่อนที่ 100m บน iOS งานเบื้องหลังทุก 15 นาทีบน Android และ spatial index ในฐานข้อมูล
ความปลอดภัยพื้นฐาน — มีกฎการเข้าถึงทุกตาราง
กฎการเข้าถึงระดับแถว (row-level) ครบทั้ง 22 ตาราง (47 policy) และเก็บคีย์ไว้ฝั่งเซิร์ฟเวอร์
↗ ขั้นต่อไป (กำลังเติมเต็ม)5
การทดสอบและระบบอัตโนมัติ — มีการทดสอบเฉพาะเอนจินจับคู่
มีการทดสอบแบ็กเอนด์ 8 ชุดสำหรับการจับคู่ ไม่มีสำหรับตัวแอป และไม่มี CI
วางแผน → ทดสอบ flow การจับคู่บัญชี การจับคู่ช่วงเวลา และการซื้อ พร้อม CI สำหรับทั้งสองแอป
การเปิดตัวและการดูแลระบบ — ฐานข้อมูลจริงไม่ตรงกับ repository
repo ของแบ็กเอนด์หยุดอัปเดตตั้งแต่ต้นเดือนพฤษภาคม ขณะที่ฐานข้อมูลจริงยังเปลี่ยนต่อเนื่อง
วางแผน → ดึง schema จริงออกมาเป็นไฟล์ migration คอมมิตเข้า repo และเลิกแก้ผ่านแดชบอร์ดอย่างเดียว
ความปลอดภัย — เสริมความแข็งแรงก่อนเปิดตัวบนสโตร์
จะเพิ่มการตรวจสอบการซื้อฝั่งเซิร์ฟเวอร์อีกชั้นก่อนเปิดตัวบนสโตร์ และจะแสดงข้อผิดพลาดออกมาแทนการกลบไว้
วางแผน → ตรวจสอบการซื้อฝั่งเซิร์ฟเวอร์ และรายงานข้อผิดพลาดอย่างเหมาะสม
ความสมบูรณ์ของ Android — Android ตามหลัง iOS
ผมทำ iOS เสร็จก่อน Android กำลังพัฒนาอยู่
วางแผน → ทำ Android ให้เท่า iOS โดยใช้รายการฟีเจอร์ของ iOS เป็นหลัก — ไม่ใช่คัดลอกโค้ด
การเข้าถึง (Accessibility) — มี label เฉพาะหน้าจอหลัก
label สำหรับโปรแกรมอ่านหน้าจอ 23 จุดบน iOS และราว 10 จุดบน Android
วางแผน → label และการปรับขนาดตัวอักษรจะเป็นรายการในเช็กลิสต์ก่อนเปิดตัว
Chapter 03
Chapter takeaway
สิ่งที่โปรเจกต์นี้สอนผม
01 ฟีเจอร์เดียวกันออกแบบต่างกันในแต่ละแพลตฟอร์ม — อย่าคัดลอก ให้สั่งแยกกัน02 ตรรกะที่ไม่นิ่ง (การเทียบตำแหน่ง) ควรย้ายจากไคลเอนต์ไปไว้บนเซิร์ฟเวอร์03 เมื่อผลงานของ AI ติดขัด ให้ชี้ที่สาเหตุ (รูปแบบวันที่ DI) แล้วสั่งใหม่อย่างเจาะจงโปรเจกต์ถัดไป →
ดีไซน์ของนักวางแผน สร้างด้วย AI — ระบบลงเวลาทำงานด้วย NFC + GPS พร้อมคำนวณเงินเดือนอัตโนมัติ สำหรับธุรกิจขนาดเล็กในไทย
© 2026 Hyunjun Kim. สร้างด้วย Next.js, Tailwind CSS และ Motion — ร่วมกับ AI
Back to top ↑