본문 바로가기

Develop

Flutter와 GetX로 가게 검색 앱 개발기: 상태관리의 시작부터 배포까지

안녕하세요! 오늘은 Flutter와 GetX를 사용하여 지역 가게 검색 앱을 개발한 경험을 공유하려고 합니다. 처음 Flutter로 프로젝트를 시작할 때 많은 고민이 있었는데요, 특히 상태관리 라이브러리 선택에서 Provider, Bloc, GetX 등 다양한 옵션 중에서 어떤 것을 선택할지 많은 고민이 있었습니다.

결국 GetX를 선택하게 된 이유와 개발 과정에서 겪은 다양한 도전과 해결 방법들을 공유하려고 합니다.

 

프로젝트 개요

기획 의도

  • 지역 상권 활성화를 위한 가게 정보 제공
  • 사용자 위치 기반 주변 가게 탐색
  • 낮/밤 시간대별 추천 가게 제공
  • 카테고리별 필터링 기능

주요 기능

  1. 지도 기반 가게 위치 표시
  2. 카테고리별 가게 필터링
  3. 낮/밤 시간대별 가게 목록
  4. 가게 상세 정보 보기
  5. 검색 기능

기술 스택 선정

GetX를 선택한 이유

  1. 간단한 상태관리
  2. 의존성 주입의 용이성
  3. 라우트 관리 기능 통합
  4. 적은 보일러플레이트 코드
class StoreController extends GetxController {
  // 반응형 상태 관리를 위한 Observable 변수들
  final searchQuery = ''.obs;
  final filteredStores = <Store>[].obs;
  final selectedStore = Rx<Store?>(null);

  // 낮/밤 가게 목록을 위한 Observable 리스트
  final dayStores = <Store>[].obs;
  final nightStores = <Store>[].obs;

  // 로딩 상태 관리
  final isLoadingDay = true.obs;
  final isLoadingNight = true.obs;
}

프로젝트 구조

lib/
  ├── controllers/     # GetX 컨트롤러
  ├── models/         # 데이터 모델
  ├── screens/        # 화면 UI
  ├── widgets/        # 재사용 가능한 위젯
  └── services/       # API 및 비즈니스 로직

주요 개발 포인트

1. 매력적인 UI 구현하기

가게 카드 UI는 사용자의 시선을 끌면서도 필요한 정보를 한눈에 볼 수 있도록 구성했습니다.

Widget _buildStoreCard(Store store) {
  return GestureDetector(
    onTap: () => StoreMapBottomSheet.show(context, store),
    child: Container(
      margin: const EdgeInsets.symmetric(horizontal: 5.0),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(15),
        color: Colors.white,
        boxShadow: [
          BoxShadow(
            color: Colors.grey.withOpacity(0.4),
            spreadRadius: 1,
            blurRadius: 5,
            offset: const Offset(0, 3),
          ),
        ],
      ),
      child: Column(
        children: [
          // 가게 정보 표시
          Text(store.name),
          Text(store.shortDescription),
          // ... 기타 정보들
        ],
      ),
    ),
  );
}

2. 효율적인 상태 관리

GetX의 반응형 프로그래밍 모델을 활용하여 상태 관리를 구현했습니다.

void filterStores() {
  if (searchQuery.value.isEmpty && selectedCategory.value.isEmpty) {
    filteredStores.value = stores;
  } else {
    filteredStores.value = stores.where((store) {
      final matchesSearch = searchQuery.value.isEmpty ||
          store.name.toLowerCase().contains(searchQuery.value.toLowerCase()) ||
          store.category.toLowerCase().contains(searchQuery.value.toLowerCase());

      final matchesCategory = selectedCategory.value.isEmpty ||
          store.category == selectedCategory.value;

      return matchesSearch && matchesCategory;
    }).toList();
  }
}

3. 지도 통합과 위치 기반 서비스

Google Maps를 활용하여 가게 위치를 시각적으로 표시하고, 사용자 위치 기반 서비스를 구현했습니다.

class StoreMapBottomSheet extends StatelessWidget {
  static void show(BuildContext context, Store store) {
    showMaterialModalBottomSheet(
      context: context,
      expand: true,
      enableDrag: true,
      backgroundColor: Colors.transparent,
      builder: (context) => StoreMapBottomSheet(store: store),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: [
          // 구글 맵 표시
          Container(
            height: 300,
            child: GoogleMap(
              initialCameraPosition: CameraPosition(
                target: LatLng(store.lat, store.lng),
                zoom: 15,
              ),
              markers: {
                Marker(
                  markerId: MarkerId(store.id.toString()),
                  position: LatLng(store.lat, store.lng),
                ),
              },
            ),
          ),
          // 가게 상세 정보
        ],
      ),
    );
  }
}

개발 과정에서 배운 점

1. GetX의 장단점

장점:

  • 간단한 상태 관리
  • 적은 보일러플레이트 코드
  • 통합된 라우팅 시스템

단점:

  • 커뮤니티 규모가 Provider에 비해 작음
  • 디버깅이 때로는 까다로움

2. 성능 최적화

  • 리스트 아이템 렌더링 최적화
  • 이미지 캐싱 처리
  • 지도 마커 업데이트 최적화

3. 사용자 경험 개선

  • 부드러운 애니메이션 적용
  • 직관적인 내비게이션 구조
  • 반응형 디자인 적용

향후 개선 계획

  1. 기능 개선
    • 사용자 리뷰 시스템 도입
    • 개인화된 추천 시스템
    • 소셜 기능 추가
  2. 기술적 개선
    • 테스트 코드 보강
    • 에러 처리 개선
    • 문서화 강화
  3. 성능 최적화
    • 대규모 데이터 처리 최적화
    • 지도 마커 클러스터링
    • 캐시 시스템 도입

마치며

Flutter와 GetX를 활용한 개발은 전반적으로 만족스러운 경험이었습니다. 특히 GetX의 반응형 프로그래밍 모델은 상태 관리를 매우 직관적으로 만들어주었고, Flutter의 위젯 시스템은 아름답고 반응성 높은 UI를 구현하는 데 큰 도움이 되었습니다.

앱 개발에서 가장 중요한 것은 결국 사용자 경험이라고 생각합니다. 기술 스택의 선택도 중요하지만, 그것을 어떻게 활용하여 사용자에게 가치를 전달할 수 있는지가 더 중요한 것 같습니다.

이 글이 Flutter와 GetX를 시작하시는 분들께 도움이 되었기를 바랍니다. 추가로 궁금하신 점이나 더 자세히 알고 싶으신 부분이 있다면 댓글로 남겨주세요.

참고 자료


이 개발기는 실제 프로덕션 앱 개발 경험을 바탕으로 작성되었습니다.

 

이전글

https://pointer81.tistory.com/entry/activate-gaksan-village-project

 

각산마을 상권 활성화 프로젝트: 디지털로 되살리는 우리 동네

1. 프로젝트 개요프로젝트 배경과 목적내가 태어나고 자란 고향 각산마을의 상권을 부활시키고 싶은 마음에서 시작했습니다. 현재 종이 지도로만 제공되는 상점 정보를 디지털화하여, 더 많은

pointer81.tistory.com

 

https://pointer81.tistory.com/entry/flutter-local-business-map-5-day-journey

 

Flutter로 '각산마을' 지도 앱 개발기

5일간의 앱 개발 여정 공유최초 작성일: 2024년 11월 20일카테고리: 모바일 개발/Flutter목차프로젝트 소개개발 과정기술적 도전과 해결주요 기능 구현최적화 및 분석마치며프로젝트 소개'각산마을'

pointer81.tistory.com

 

아이디어 제안, 디자인, 개발 모두 참여 가능합니다. 

https://bit.ly/3CCxWih

반응형