교대근무를 하다 보면 내 다음 출근일이 언제인지 매번 확인하는 게 귀찮았다. 그래서 홈화면 위젯으로 바로 확인할 수 있는 앱을 직접 기획하고 만들었다.
shift_widget_app: 사이클 기반 교대근무 일정 관리 앱으로, iOS/Android 홈화면 및 잠금화면 위젯을 지원한다.
이 프로젝트는 Anthropic의 AI 코딩 도구인 Claude Code와 함께 진행했다.
앱의 기획과 방향은 내가 잡았고, 구현은 Claude Code가 도와줬다.
Flutter나 각 기술 스택을 깊게 알고 있는 상태는 아니었지만, Claude Code 덕분에 원하는 앱을 완성할 수 있었다.
Claude Code는 Anthropic이 만든 AI 코딩 어시스턴트로, 터미널에서 직접 코드를 작성하고 실행하며 프로젝트 전체를 이해하는 AI 도구다.
단순히 코드를 생성하는 것을 넘어서, 버그를 찾아 수정하고, 테스트를 작성하고, 아키텍처 설계까지 함께 논의할 수 있다. 이번 프로젝트에서는 TDD(Red-Green-Refactor)를 적용해서 버그를 수정하고 총 50개의 테스트를 작성하는 데 활용했다.
선택 이유: iOS와 Android를 하나의 코드베이스로 개발할 수 있어서. 특히 위젯 같은 플랫폼별 기능은 별도로 구현해야 하지만, 앱 코어 로직은 공유할 수 있다.
배운 점:
ConsumerStatefulWidget을 기본 단위로 사용하면 Riverpod과 자연스럽게 통합된다선택 이유: Provider의 단점을 보완한 라이브러리. 컴파일 타임 안전성과 테스트 용이성이 좋았다.
배운 점:
ref.watch() vs ref.read() 구분이 중요하다. 화면 갱신이 필요하면 watch, 이벤트 핸들러에서는 read선택 이유: Flutter에서 가볍고 빠른 NoSQL 로컬 저장소. 별도 서버 없이 기기 내에서 모든 데이터를 처리하는 앱에 적합했다.
배운 점:
UserDefaults(iOS) / SharedPreferences(Android)에 별도 저장 — 위젯은 앱의 Hive에 직접 접근할 수 없다선택 이유: Flutter 공식 권장 라우팅 패키지. 선언적 라우팅과 딥링크 지원이 좋았다.
배운 점:
redirect 기능으로 초기 세팅 분기 처리를 깔끔하게 할 수 있다선택 이유: iOS 14+에서 홈화면 위젯을 구현하는 공식 프레임워크.
배운 점:
systemSmall, systemMedium, systemLarge + accessoryCircular, accessoryRectangular, accessoryInline@Environment(\.widgetFamily)로 현재 위젯 종류를 읽어 분기 처리UserDefaults App Group에 저장하고, 위젯에서 읽는 구조선택 이유: Android에서 Compose 스타일로 위젯을 만들 수 있는 최신 라이브러리.
배운 점:
SizeMode.Responsive로 위젯 크기에 따라 UI를 다르게 렌더링할 수 있다SharedPreferences에 저장하고 위젯에서 읽어오는 구조솔직히 말하면 Flutter를 깊게 공부한 상태에서 시작한 프로젝트가 아니었다. 앱을 만들고 싶다는 기획과 아이디어는 있었지만, 구현 방법은 잘 몰랐다.
Claude Code는 단순히 코드를 대신 써주는 도구가 아니었다. 왜 이렇게 구현하는지 설명해주고, 버그가 생겼을 때 원인을 분석해서 TDD 방식으로 함께 고쳐나갔다. 덕분에 기술 스택 각각의 역할과 사용 이유를 자연스럽게 이해할 수 있었다.
AI 도구를 활용해서 앱을 만드는 게 어떤 경험인지 궁금했는데, 생각보다 훨씬 좋은 경험이었다. 앞으로도 이런 방식으로 다양한 프로젝트를 진행해볼 생각이다.
이 앱을 만들면서 Flutter 앱 개발 전반과 iOS/Android 네이티브 위젯 연동까지 경험할 수 있었다. 특히 위젯은 앱과 별개의 프로세스에서 동작하기 때문에 데이터 공유 방식을 따로 설계해야 한다는 점이 인상적이었다.
다음엔 위젯 디자인을 더 다듬고, 알림 기능을 고도화해보고 싶다.