본문 바로가기

카테고리 없음

flutter 앱 제작기

Flutter로 시니어 웰니스 사운드 앱 MVP 개발기

Repository Pattern, 듀얼 오디오 믹싱, 환경 분리 적용기

 

친한 친구를 돕게되어 시니어 세대를 위한 사운드 테라피 앱 MVP를 Flutter로 개발하고 있다. 수면, 명상, 휴식을 돕는 것을 목표로 기분 기반 음악 추천, 듀얼 오디오 재생, 백그라운드 재생, 시니어 친화 UI를 구현 중이다. 사용자 테스트는 아직 진행하지않았지만 곧 진행예정이며, 1인 개발로 첫 버전을 만들고 있다.


주요 기능

  • 기분 기반 음악 추천
    사용자의 기분 데이터를 기반으로 맞춤 음악을 추천하는 기능이다.
  • 듀얼 오디오 믹싱
    메인 음악과 자연음을 동시에 재생하며, 각 볼륨을 독립적으로 조절할 수 있다.
  • 백그라운드 재생 지원
    앱이 백그라운드에 있을 때도 음악이 끊기지 않고 계속 재생된다.
  • 시니어 친화 UI/UX
    동적 폰트 크기, 큰 터치 영역, 명확한 버튼 피드백 등 사용성을 고려했다.
  • 피드백 수집 시스템
    청취 후 사용자 의견을 자동 타이머로 수집하는 기능을 준비 중이다.

Repository Pattern과 Fallback 전략

초기에는 UI 단에서 Supabase API를 직접 호출했다. 이 구조는 네트워크 불안정 시 바로 실패하고, Mock 테스트나 데이터 소스 변경 시 UI 코드까지 수정해야 했다.

이를 개선하기 위해 Repository Pattern과 Fallback 전략을 결합했다.

  • Primary Repository: Supabase API 호출
  • Fallback Repository: 로컬 JSON 로드
  • API 호출 실패 시 자동으로 Fallback 데이터를 반환

데이터 접근 로직이 UI와 분리되면서 테스트 작성이 쉬워졌고, 오프라인 모드 지원도 가능해졌다.

또한 환경별로 데이터 소스를 전환할 수 있도록 .env를 활용했다.

  • ENV=production → Supabase 우선
    이렇게 구성해 동일한 코드베이스로 개발·프로덕션 환경을 유연하게 전환할 수 있었다.

듀얼 오디오 믹싱 구현

앱의 핵심 경험 중 하나는 메인 음악과 자연음을 동시에 재생하는 것이다. just_audio 패키지로 플레이어를 2개 두고, 각 볼륨을 독립적으로 조절할 수 있도록 했다. 자연음은 무한 반복하고, 사용자가 슬라이더로 메인/자연음 비율을 조정하면 즉시 반영된다.
자연음은 총 6가지를 선택할수 있도록 했으며, 메인 트랙에서도 들을수 있다. 최대한 쉽게 적용해볼 수 있도록 고민했는데 잘 될지 모르겠다. 

백그라운드 재생을 생각 못했었는데 해당부분은 구현할 예정이다.


시니어 친화 UI 설계

시니어 사용자는 작은 글씨와 좁은 버튼을 불편해한다. 이를 고려해 다음을 적용했다.

  • 글씨 크기 동적 조절 (4단계 => 사실 추후에 줄어들 것 같다.)
  • 큰 터치 영역과 직관적인 아이콘
  • 버튼 클릭 시 햅틱 피드백 제공

아직 테스트 전이지만, 실제 사용성에 어떻게 영향을 줄지 피드백이 기대되는 부분이다.


데이터베이스 구조

PostgreSQL로 테마와 트랙을 관리하고 있다.

  • 다대다 관계를 관계 테이블(theme_tracks)로 처리
  • 피드백 테이블에 청취 맥락을 함께 저장해 추천 품질 개선에 활용

성능과 안정성

  • 이미지 캐싱으로 로딩 지연 최소화
  • 데이터 프리페칭으로 앱 시작 시 전체 트랙 로드
  • 3단계 재시도 로직으로 불안정한 네트워크에서도 안정적인 동작 유지

이번 MVP 개발에서 느낀 점은 앱개발이 참 쉽지않으면서도 재밌구나 싶은점이다. 작은 화면에 뭐 이렇게 복잡한게 많이 들어있는지. 아직 개발걸음마면서 올해 참 여러가지 무리하게 해나가고 있다. 근데 계속 이것저것 해나가다보면 경험이 쌓이면서 무기로 전환될 날이 오지않을까 싶다. 결함, 오류들은 계속해서 수정해나갈 예정이며, 곧 사용자 테스트를 거치며 실사용 피드백을 반영할 예정이다. 사용자의 직접피드백, 그리고 실제 비즈니스에서의 피드백까지도 기다리고 있는데 열심히 책임감있게 해봐야지.