Back to projects

천원 쓰레기통

Mobile

프로젝트 개요

천원 쓰레기통은 1000원을 내면 재미를 주는 독특한 콘셉트의 모바일 애플리케이션입니다. Raph Koster는 재미를 학습의 보상으로 정의하는데, 이 프로젝트는 '누가 가장 많은 돈을 버렸는가'라는 패턴 찾기를 통해 사용자에게 재미를 제공합니다.

이 앱은 실용적인 가치나 놀라운 기능을 제공하지 않습니다. 단지 1000원을 내면 감사하다는 메시지와 함께 리더보드에 등록할 수 있는 기회를 제공합니다. 사용자들은 리더보드에서 총 후원 금액을 기준으로 랭킹을 경쟁하며, 이 쓸모없는 경쟁에 동참하여 자신의 이름을 최상단에 올리는 것을 목표로 합니다.

프로젝트의 핵심은 사용자의 내재적 동기를 자극하는 것입니다. 자율성, 유능성, 관계성을 보장하면서 후원하는 사용자를 유능하다고 치켜세우고, 후원이 개발자에게 큰 도움이 된다는 메시지를 전달합니다.

기술 스택

이 프로젝트는 React Native, Expo, Supabase를 기반으로 구축되었습니다. React Native는 크로스 플랫폼 모바일 앱 개발을 가능하게 하여 iOS와 Android를 동시에 지원할 수 있게 합니다. Expo는 개발 환경을 단순화하고 빠른 프로토타이핑을 가능하게 하는 도구로 선택되었습니다.

백엔드 인프라로는 Supabase를 사용하여 사용자 인증, 데이터베이스 관리, 실시간 데이터 동기화를 처리합니다. 리더보드 데이터는 Supabase의 PostgreSQL 데이터베이스에 저장되며, 실시간으로 업데이트되어 사용자들에게 최신 랭킹 정보를 제공합니다.

결제 시스템은 Google Play의 인앱 결제(In-App Purchase) API를 통합하여 구현되었습니다. 이를 통해 안전하고 신뢰할 수 있는 결제 프로세스를 제공하며, 후원자 배지와 같은 Google Play의 기능도 활용합니다.

주요 기능

후원 시스템

홈 스크린에는 '여기에 천원 버리기'라는 메인 버튼이 배치되어 있습니다. 사용자가 이 버튼을 누르면 즉시 Google Play 결제 화면으로 이동하여 1000원을 후원할 수 있습니다. 결제가 취소되면 사용자에게 다이얼로그를 통해 알리고 메인 화면으로 돌아옵니다.

결제가 성공하면 시스템은 최초 후원 여부를 자동으로 검증합니다. 최초 후원자에게는 특별한 감사 메시지 화면과 함께 Google Play의 후원자 배지가 지급됩니다. 이후 닉네임 설정 화면으로 이동하여 리더보드에 등록할 수 있습니다.

두 번째 이후 후원부터는 닉네임이 이미 로컬 데이터베이스에 저장되어 있으므로 닉네임 입력 과정을 건너뛰고 바로 후원 완료 화면을 표시합니다. 이를 통해 반복 후원자에게 더 빠르고 간편한 경험을 제공합니다.

리더보드 시스템

리더보드는 '이달의 쓰레기왕'이라는 타이틀로 표시되며, 두 가지 섹션으로 구성됩니다. 첫 번째는 총 후원 금액을 기준으로 한 Top Ranker 섹션이고, 두 번째는 최근 후원한 사용자들을 보여주는 섹션입니다.

1위부터 3위까지는 특별한 테두리와 함께 강조 표시되어 상위 랭커들에게 성취감을 제공합니다. 리더보드 진입 시에는 top-down fade-in 애니메이션이 적용되며, 새로운 후원자가 등록되면 '최근 후원' 섹션에 slide-in 애니메이션이 재생됩니다.

순위 변동이 발생하면 숫자 카운팅 애니메이션을 통해 시각적 피드백을 제공합니다. 이러한 애니메이션 효과들은 사용자의 참여를 유도하고 후원 행위에 대한 즉각적인 보상감을 제공하는 역할을 합니다.

닉네임 설정 및 중복 처리

닉네임 설정 화면은 '리더보드에 등록하세요!'라는 안내 문구와 함께 최대 12자까지 입력할 수 있는 텍스트 필드를 제공합니다. 확인 버튼은 2자 이상 입력되었을 때만 활성화되어 너무 짧은 닉네임을 방지합니다.

사용자가 확인 버튼을 클릭하면 시스템은 서버에서 닉네임 중복 여부를 검사합니다. 중복 닉네임이 없다면 바로 후원 완료 화면으로 이동하여 현재 순위와 총 후원 금액을 표시합니다.

만약 중복 닉네임이 존재한다면 '중복된 닉네임' 다이얼로그를 띄웁니다. 다이얼로그에는 "이미 사용 중인 닉네임입니다. 그래도 사용하시겠습니까? 동명이인으로 표시됩니다."라는 메시지와 함께 '아니오'와 '예, 사용할게요' 버튼이 제공됩니다. 사용자가 '아니오'를 선택하면 다시 닉네임 입력 화면으로 돌아가고, '예'를 선택하면 해당 닉네임으로 등록됩니다.

공유 기능

후원 완료 화면에는 '친구에게 자랑하기' 버튼이 배치되어 있습니다. 이 버튼을 누르면 뒷 배경이 반투명 검은색으로 변하고, 화면 하단에서 공유 플랫폼 선택 박스가 슬라이드 업 애니메이션과 함께 나타납니다.

공유 가능한 플랫폼으로는 카카오톡, 인스타그램, 페이스북, 트위터, 링크 복사, 문자 메시지 등이 포함됩니다. 각 플랫폼은 아이콘으로 표시되며, 사용자가 선택한 플랫폼을 통해 자신의 후원 성과를 공유할 수 있습니다.

공유 메시지는 다음과 같은 템플릿을 사용합니다: "나도 천원 쓰레기통에 천원을 버렸어요! 💸 현재 [순위]위로 등극! 총 후원 금액: [금액]원 [앱 링크]" 사용자가 배경의 다른 곳을 터치하거나 취소 버튼을 누르면 공유 화면이 닫힙니다.

다국어 지원

앱은 사용자의 시스템 언어 설정을 자동으로 감지하여 적절한 언어로 인터페이스를 표시합니다. 이를 통해 다양한 국가의 사용자들이 자신에게 친숙한 언어로 앱을 사용할 수 있으며, 글로벌 사용자 베이스를 확보할 수 있습니다.

사용자 경험 설계

온보딩 스크린

앱을 처음 설치하고 실행하는 사용자는 무엇을 하는 앱인지, '천원을 버린다'는 의미가 무엇인지 궁금해할 것입니다. 온보딩 화면은 이러한 궁금증을 해소하고 사용자의 참여를 유도하는 역할을 합니다.

온보딩 화면에서는 "이 앱은 아무것도 아닙니다! 그냥 후원해주세요."라는 솔직한 메시지를 통해 앱의 콘셉트를 명확히 전달합니다. 동시에 후원하는 사용자를 유능하다고 치켜세우고, 후원이 개발자에게 큰 도움이 된다는 문구를 통해 내재적 동기를 자극합니다.

메인 화면 구성

메인 화면은 사용자가 앱에 들어오자마자 후원 버튼과 리더보드를 동시에 볼 수 있도록 설계되었습니다. 이는 "이 버튼을 눌러 후원하면 나도 리더보드에 등록될 수 있겠구나"라는 생각을 자연스럽게 유도합니다.

후원 버튼은 충분히 크게 디자인되어 눈에 잘 띄지만, 화면을 너무 많이 가리지 않아 리더보드도 잘 보이도록 균형을 맞추었습니다. Top Ranker와 최근 후원자라는 두 가지 리더보드 섹션을 동시에 보여줌으로써 사용자의 참여 동기를 극대화합니다.

후원 완료 화면

후원이 완료되면 사용자에게 명확한 피드백을 제공하는 화면이 표시됩니다. 화면에는 "후원 완료!", 사용자의 닉네임, 총 후원 금액, 현재 순위가 표시되며, '친구에게 자랑하기'와 '홈으로 돌아가기' 두 가지 버튼이 제공됩니다.

이 화면은 사용자의 후원 행위를 인정하고 축하하는 역할을 하며, 동시에 소셜 공유를 통해 앱의 바이럴 확산을 유도합니다.

예외 처리 및 오류 대응

결제 실패 처리

결제 처리 중 문제가 발생하면 "❌ 결제 실패" 다이얼로그를 표시합니다. 다이얼로그에는 "결제 처리 중 문제가 발생했습니다."라는 메시지와 함께 '다시 시도'와 '취소' 버튼이 제공됩니다. '다시 시도'를 선택하면 결제 화면을 유지하고, '취소'를 선택하면 홈 스크린으로 복귀합니다.

네트워크 연결 실패

네트워크 연결이 안 되어 리더보드 로딩이 실패하면 홈 스크린에 "🌐 연결 확인 중... 리더보드를 불러올 수 없습니다."라는 빈 상태 메시지를 표시합니다. 백그라운드에서 자동으로 최대 3회까지 재시도하며, 수동 새로고침 버튼도 제공합니다.

오프라인 모드에서는 캐시된 리더보드를 표시하고 마지막 업데이트 시간을 함께 보여줍니다. 후원 버튼은 비활성화되며 "인터넷 연결이 필요합니다"라는 메시지를 표시하여 사용자에게 현재 상태를 명확히 알립니다.

닉네임 저장 실패

만약 닉네임 설정 중에 앱을 종료하거나 저장에 실패한 경우, 다음 접속 시 "⚠️ 저장 실패" 다이얼로그를 표시합니다. 다이얼로그에는 "닉네임을 저장하지 못했습니다."라는 메시지와 함께 '이어서 닉네임 설정하기' 버튼이 제공되며, 이를 클릭하면 닉네임 설정 화면으로 이동합니다.

디자인 철학

이 프로젝트의 디자인에는 명확한 근거가 있습니다. 각 스크린은 사용자의 요구와 욕구를 파악하여 설계되었으며, 사용자가 무슨 목적을 가지고 들어왔는지를 이해하고 그 목적을 해결해주는 것을 최우선으로 합니다.

스크린과 다이얼로그의 구분도 명확한 기준에 따릅니다. 주요 사용자 플로우와 정보 제공은 전체 스크린으로, 확인이나 경고와 같은 일시적인 상호작용은 다이얼로그로 처리하여 사용자 경험의 일관성을 유지합니다.