2025년 4월 11일, 스터디덕 개발 일지
안녕하세요. 저는 플러터 개발자를 꿈꾸는 50세 개발자입니다.
요즘 집중력 향상 앱인 ‘스터디덕(Study Duck)’을 개발하며 사용자에게 도움이 되는 기능을 하나씩 추가하고 있습니다.
오늘은 제가 실제로 겪은 Hive 데이터 모델 업데이트 문제와 그것을 어떻게 해결했는지를 공유하려고 합니다.
Flutter로 앱을 개발하시는 분들, 특히 Hive를 사용하는 분들께 도움이 되길 바랍니다.
기능 추가 배경
스터디덕은 공부에 집중하는 시간을 늘리기 위해 만든 앱입니다.
최근 유저들에게 집중 호흡 모드 기능을 제공하고 싶었습니다.
그래서 앱 설정에 아래와 같은 필드를 추가했습니다.
@HiveField(5) @Default(true) bool autoBreathingExercise,
즉, 유저가 집중 타이머를 사용할 때 자동으로 호흡 유도 애니메이션이 실행될지 여부를 선택할 수 있도록 구현한 것이죠.
앱을 배포했더니… 친구들이 앱이 멈춘다고?
문제는 이 필드를 추가하고 앱을 Play Store에 업데이트 배포한 뒤 발생했습니다.
몇몇 지인들이 앱을 실행하자마자 멈춘다고 연락을 주셨습니다.
"화면이 안 넘어가요", "앱이 먹통이에요"라는 반응에 순간 당황했습니다.
문제 원인: Hive에 bool 필드를 추가했을 뿐인데?
처음엔 UI 문제인가 싶어 이것저것 로그를 찍어봤지만, 문제는 바로 Hive 모델 업데이트 방식이었습니다.
Hive는 데이터 구조가 변경되면, 예전 버전의 앱에서 사용하던 데이터가 새로운 구조를 읽지 못할 수 있습니다.
특히 @HiveField(5)처럼 새 필드를 추가하면,
기존 사용자에게는 해당 필드가 없기 때문에 null 값을 bool로 강제 캐스팅하면서 앱이 크래시 나는 것이었습니다.
autoBreathingExercise: fields[5] as bool, // ← null일 수 있음!
해결 방법: null-safe 수동 어댑터 작성
해결을 위해 저는 자동 생성된 어댑터가 아닌 수동으로 어댑터를 작성했습니다.
핵심은 새 필드가 없을 경우 기본값을 주는 방식입니다.
autoBreathingExercise: fields.containsKey(5)
? fields[5] as bool
: true, // 기본값 true로 대체
전체 코드 예시는 아래와 같으며, 직접 만든 어댑터를 Hive.registerAdapter()로 등록하면 됩니다.
class AppSettingAdapter extends TypeAdapter<AppSetting> {
@override
final int typeId = 12;
@override
AppSetting read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return AppSetting(
color: fields[0] as String,
fontSize: fields[1] as int,
language: fields[2] as String,
isFirstInstalled: fields[3] as bool,
autoFocusMode: fields[4] as bool,
// 앱크러쉬를 막기위해 수정된 코드
autoBreathingExercise: fields.containsKey(5)
? fields[5] as bool
: true,
);
}
@override
void write(BinaryWriter writer, AppSetting obj) {
writer
..writeByte(6)
..writeByte(0)
..write(obj.color)
..writeByte(1)
..write(obj.fontSize)
..writeByte(2)
..write(obj.language)
..writeByte(3)
..write(obj.isFirstInstalled)
..writeByte(4)
..write(obj.autoFocusMode)
..writeByte(5)
..write(obj.autoBreathingExercise);
}
}
해결 이후
이 수동 어댑터를 적용하고 앱을 재배포한 후, 모든 유저가 문제없이 앱을 실행할 수 있게 되었습니다.
Hive는 가볍고 빠르지만, 모델 변경 시 반드시 백워드 호환성을 고려해야 한다는 교훈을 얻었습니다.
마무리하며
이번 경험은 저에게 큰 배움이었습니다.
“그냥 필드 하나 추가한 것뿐인데 앱이 멈춘다고?” 라는 말이 처음에는 와닿지 않았지만,
실제 앱에서 수천 명의 유저가 사용하는 상황이라면 사소한 변경도 큰 문제가 될 수 있겠다는 걸 느꼈습니다.
Flutter + Hive 조합을 사용하신다면,
업데이트 전에 꼭 기존 데이터와 호환성 테스트를 진행하세요.
요약
- Hive 모델에 새 필드를 추가하면 기존 유저에서 앱이 멈출 수 있다.
- 자동 생성 어댑터는 null-safe 처리를 하지 않기 때문에 주의해야 한다.
- 수동 어댑터를 만들어서 fields.containsKey()로 예외 상황을 처리하자.
- 앱을 배포하기 전 반드시 기존 유저 데이터에 대한 테스트를 하자.
"당신의 학습 스타일에 맞춘 효율적인 학습, Study Duck과 함께하세요!"
MBTI에 따라 맞춤형 학습법을 적용하면, 학습 효과가 두 배로! 혼자 학습하면 빠르게 배울 수 있지만, Study Duck은 꾸준히 장기간 학습을 도와줍니다.
학습 타이머로 집중을 유지하고, 리더보드에서 다른 사람들과 경쟁하며 꾸준함을 유지하세요.
지금 바로 Study Duck으로 학습의 새로운 장을 열어보세요!
Study Duck - Smart Learning Assistant
Enhance your study efficiency with personalized MBTI learning strategies, focus mode, and white noise.
studyduck.net
'50 year old flutter developer challenge' 카테고리의 다른 글
[50살에 플러터 개발 도전기] Study Duck : Drawer 애니메이션으로 화이트노이즈 컨트롤의 UX 개선하기 (0) | 2025.04.20 |
---|---|
[50살에 플러터 개발 도전기] Study Duck 보고서 및 마케팅 플렌 작성기 (1) | 2025.04.18 |
[50살에 플러터 개발 도전기] 구글플레이스토어에 스터디덕 첫 프로덕션 배포 시작 (0) | 2025.03.29 |
[50살에 플러터 개발 도전기] 스터디 덕의 새로운 도전: 비공개 테스트 통과와 디자인 개선 (1) | 2025.03.25 |
[50살에 플러터 개발 도전기] 새싹을 수료한 이야기: Study Duck 앱의 첫 발을 떼다 (0) | 2025.03.11 |