바이브코딩

MRALA 개발 로그: Codex와 함께 앱을 다듬은 기록

ByBed에서 MRALA로 이름을 바꾸고, Dynamic Island, Live Activity, Apple Watch, App Store 제출까지 이어진 개발 과정을 정리했다.

A laptop screen with code and product work

MRALA는 처음부터 새로 만든 앱이라기보다, ByBed라는 기존 수면 루틴 앱을 실제로 쓸 수 있는 형태로 계속 밀어붙인 프로젝트에 가깝다. 목표는 단순했다. 밤에 앱을 열었을 때, 잠금화면이나 Dynamic Island를 봤을 때, Apple Watch를 봤을 때 지금 해야 할 일이 분명해야 했다.

이 과정에서 Codex를 숨겨 쓰지 않았다. 코드를 읽고, 수정 지점을 찾고, 빌드하고, 실제 기기에 넣어보고, App Store Connect 제출 상태까지 확인하는 반복 작업에 Codex를 적극적으로 썼다. 대신 제품 판단은 계속 사람이 했다. 어떤 정보가 너무 많아 보이는지, 어떤 문장이 앱 화면에 남으면 방해되는지, 어떤 기능이 진짜 밤에 도움이 되는지는 직접 피드백하고 다시 고쳤다.

이름부터 실제 기기까지

처음 큰 작업은 ByBed를 MRALA로 바꾸는 일이었다. 앱 이름만 바꾸는 정도가 아니라 XcodeGen 설정, 표시 이름, 앱 진입점, 번들 관련 표면을 훑어야 했다. 특히 이 앱은 말로만 동작하는 샘플이 아니라 실제 iPhone에 설치해서 써야 했기 때문에, 빌드 성공보다 설치와 실행 확인이 더 중요했다.

이름이 MRALA로 보이고, 실제 아이폰에서 실행되고, 이후 배포 단계까지 이어질 수 있게 정리한 것이 첫 번째 기준선이었다. 그 뒤부터는 기능 추가보다 “밤에 계속 곁에 있어도 거슬리지 않는가”가 핵심 질문이 됐다.

Dynamic Island와 잠금화면 피드백

가장 직접적인 피드백은 Dynamic Island가 너무 붐빈다는 것이었다. 작은 노치 영역에 수면 정보, 시간, 상태 설명을 다 넣으면 오히려 현재 시간이 가려지고, 아이폰 기본 UI처럼 느껴지지 않았다.

그래서 MRALA의 Live Activity와 Dynamic Island는 더 작고 압축된 방향으로 다시 다듬었다. 설명 문장을 줄이고, 아이콘 중심으로 바꾸고, 잠금화면에서는 필요한 정보만 남기는 쪽으로 조정했다. “보여줄 수 있는 모든 것”이 아니라 “밤에 한 번 흘깃 봐도 충분한 것”만 남기는 작업이었다.

또 하나의 기준은 잠금화면에서 쉽게 내려가거나 끊기지 않는 안정성이었다. watchOS 10 지원과 함께 Live Activity, 스케줄 런타임, 워치 동기화 흐름을 보면서 잠금화면과 워치가 서로 다른 말을 하지 않도록 맞췄다.

현재 밤만 바꾸는 기능

실사용 피드백에서 중요했던 부분은 “오늘만 일찍 자고 싶다” 같은 예외였다. 매일의 수면 계획을 다 갈아엎는 것이 아니라, 현재 밤만 임시로 바꾸는 기능이 필요했다.

그래서 현재 밤 기준의 early sleep override를 넣었다. 이 기능은 오늘 밤의 취침 관련 알림과 현재 루틴을 억제하되, 다음 날 기상 흐름까지 무너뜨리지는 않는 방향으로 설계했다. App Intents와 Live Activity 쪽에서도 이 상태를 반영해, 화면에서 토글한 상태와 실제 알림 동작이 어긋나지 않게 했다.

이후에는 “일찍 일어나기” 흐름에서 알람 억제가 제대로 적용되는지, Motion & Fitness나 HealthKit 권한 안내가 반복해서 뜨지 않는지 같은 잔여 문제를 다시 잡았다. 이런 부분은 기능 목록에는 작게 보이지만, 실제 앱에서는 피로도를 크게 좌우한다.

Apple Watch와 밤의 시각 효과

MRALA는 iPhone 화면만 보는 앱이 아니었다. Apple Watch에서도 일정과 상태가 자연스럽게 이어져야 했다. 그래서 watchOS 10부터 지원되도록 범위를 정리하고, 워치 컴플리케이션은 과하게 많은 상태를 넣기보다 시간 중심으로 읽히게 조정했다.

밤 화면의 분위기도 손봤다. 달은 너무 자주 움직이지 않게 긴 호흡으로 두고, 반딧불이는 짧은 주기로 살아 있게 만들었다. 이런 시각 효과는 기능 설명보다 감각의 문제에 가깝다. 앱이 잠을 돕겠다고 하면서 화면이 계속 조급하게 흔들리면 안 되기 때문이다.

App Store 제출까지

개발 로그에서 빼기 쉬운 부분이 배포다. 하지만 실제 프로젝트에서는 빌드가 끝이 아니었다. 버전과 빌드 번호를 올리고, App Store Connect 상태를 확인하고, 필요한 경우 다시 제출했다.

MRALA는 이 과정에서 1.0.9, 1.0.10, 1.0.11 빌드 흐름을 거쳤다. 실제 iPhone 설치와 실행 확인, App Store 제출 상태 확인, 대기 상태까지 보는 작업을 반복했다. Codex는 이 반복을 빠르게 굴리는 데 썼고, 사람이 봐야 하는 것은 “이 상태로 공개해도 되는가”였다.

Codex를 쓴다는 것

MRALA 개발에서 Codex는 단순 자동완성 도구라기보다 작업자에 가까웠다. 프로젝트 구조를 읽고, 변경 지점을 좁히고, 빌드 에러를 따라가고, 실제 기기 설치까지 확인했다. 블로그와 프로젝트 페이지를 만드는 지금도 같은 방식이다.

다만 Codex가 제품의 감각을 대신 정해주지는 않는다. “노치가 답답하다”, “이름은 MRALA여야 한다”, “워치에서도 돌아가야 한다”, “잠금화면에서 내려가면 안 된다” 같은 피드백이 있어야 개발 방향이 생긴다.

앞으로 MRALA 프로젝트 페이지에는 기능 단위 진행상황을 짧게 남기고, 큰 흐름은 이런 글로 따로 정리할 예정이다.