반응형
Flutter 커플 커뮤니티앱 개발 회고록
Flutter로 커플 앱을 개발하면서 여러 문제를 해결하는 과정에서 많은 것을 배웠다. 특히 Riverpod 상태 관리, Google Maps + Kakao API 연동, 성능 최적화, API 캐싱 등의 이슈를 다루면서 효율적인 개발 방법을 고민하게 되었다. 이 회고록에서는 개발 중 겪었던 문제, 해결 방법, 놓쳤던 부분, 그리고 성능 개선 사례를 정리해본다.
1. 부딪혔던 문제와 해결 과정
1-1. 위젯이 다시 나타날 때 데이터가 새로고침되지 않는 문제
문제:
- initState()에서 데이터를 불러오면, 해당 위젯이 처음 생성될 때만 실행되므로 화면을 다시 열었을 때 최신 데이터가 반영되지 않았다.
- setState()를 사용하여 강제로 다시 로드할 수도 있지만, 이는 비효율적이었다.
해결:
- didChangeDependencies()를 활용하여 위젯이 다시 나타날 때 데이터를 불러오도록 수정.
- ref.listen()을 사용하여 특정 상태가 변경될 때 UI가 자동으로 갱신되도록 처리.
💡 배운 점:
- initState()는 위젯이 처음 생성될 때 한 번만 실행되므로, 데이터 새로고침이 필요할 경우 didChangeDependencies()를 고려해야 한다.
- ref.listen()을 사용하면 특정 상태가 변경될 때만 UI를 업데이트할 수 있어 불필요한 리빌드를 줄일 수 있다.
1-2. 동적으로 데이트 장소 목록을 관리하는 UI 문제
문제:
- 사용자가 추가한 장소 목록을 ListView에서 관리할 때, 리스트가 정상적으로 업데이트되지 않는 경우 발생.
해결:
- ListView.builder를 사용하여 동적으로 리스트를 렌더링.
- 각 아이템에 key 값을 부여하여 상태가 꼬이지 않도록 방지.
💡 배운 점:
- ListView.builder를 활용하면 성능을 최적화할 수 있다.
- key를 설정하지 않으면 리스트 상태가 불안정해질 수 있다.
1-3. Riverpod 상태 관리 적용 문제
문제:
- Riverpod을 처음 적용하면서 상태 변경이 UI에 반영되지 않는 이슈 발생.
해결:
- StateNotifierProvider를 사용하여 상태 변경을 명확하게 관리.
- watch와 listen을 적절히 사용하여 UI 업데이트를 조정.
💡 배운 점:
- watch는 UI를 리빌드할 때 사용하고, listen은 특정 상태 변경을 감지하는 용도로 활용해야 한다.
- StateNotifierProvider를 사용하면 상태 변경을 구조적으로 관리할 수 있다.
1-4. API 반복 요청 방지 및 캐싱 적용
문제:
- 장소 데이터를 불러올 때 Kakao API를 매번 호출하여 불필요한 API 요청이 발생.
- 같은 데이터를 반복 요청하는 문제로 인해 API 호출 비용 증가 및 성능 저하.
해결:
✅ 메모리 캐싱을 활용하여 API 요청 최소화
class PlaceRepository {
final KakaoApiService apiService;
final Map<String, PlaceResponse> _cache = {}; // 메모리 캐싱
final Map<String, DateTime> _cacheTimestamp = {}; // 캐시 시간 기록
PlaceRepository(this.apiService);
static const Duration cacheDuration = Duration(minutes: 10); // 10분 캐싱 유지
Future<PlaceResponse> getPlacesByKeyword(String keyword, {String? categoryGroupCode, String? x, String? y, int? radius}) async {
String cacheKey = "keyword-$keyword-${categoryGroupCode ?? ''}-${x ?? ''}-${y ?? ''}-${radius ?? ''}";
// 캐싱된 데이터가 있고, 10분 이내에 가져온 데이터라면 API요청 없이 반환
if (_cache.containsKey(cacheKey) && DateTime.now().difference(_cacheTimestamp[cacheKey]!) < cacheDuration) {
print("🔥 캐싱된 데이터 반환 (Keyword: $keyword)");
return _cache[cacheKey]!;
}
try {
PlaceResponse response = await apiService.fetchPlacesByKeyword(keyword, categoryGroupCode: categoryGroupCode, x: x, y: y, radius: radius);
_cache[cacheKey] = response; // 데이터 캐싱
_cacheTimestamp[cacheKey] = DateTime.now();
print("✅ 새로운 API 데이터 요청 완료");
return response;
} catch (e) {
throw Exception("🔴 API 요청 실패: $e");
}
}
}
💡 배운 점:
- API 호출이 많아지면 성능 저하뿐만 아니라 불필요한 비용이 발생할 수 있다.
- 메모리 캐싱을 활용하면 같은 요청에 대한 불필요한 API 호출을 방지할 수 있다.
- 캐싱된 데이터를 일정 시간이 지나면 새로 요청하도록 하면 최신 데이터를 유지하면서도 성능을 최적화할 수 있다.
1-5. Google Maps API & Kakao 장소 API 연동 문제
문제:
- Flutter에서 Google Maps API를 사용하여 지도를 렌더링했지만, 장소 검색은 Kakao API를 활용하여 데이터를 불러와야 했다.
- Kakao API에서 검색한 장소 데이터를 Google Map에 표시하는 과정에서 좌표 변환이 필요했다.
해결:
- Kakao API에서 제공하는 좌표를 Google Maps의 LatLng 형식으로 변환하여 지도에 마커를 표시.
- google_maps_flutter 패키지를 활용하여 Google 지도 위에 Kakao에서 검색한 장소를 올바르게 매핑.
💡 배운 점:
- Kakao API와 Google Maps API를 함께 사용할 때 좌표 변환이 필요하다.
- google_maps_flutter 패키지를 사용하면 Flutter에서 쉽게 지도를 렌더링할 수 있다.
2. 성능 개선을 위한 노력
2-1. 불필요한 위젯 리빌드 최소화
- select를 활용하여 필요한 상태 변경만 감지
- const 키워드를 적극 활용하여 성능 최적화
2-2. API 캐싱 및 요청 최적화
- 메모리 캐싱 적용 (_cache 활용)
- 중복 요청 방지 (FutureProvider.autoDispose 활용)
2-3. 리스트 렌더링 최적화
- ListView.builder를 사용하여 메모리 사용 최적화
- key를 부여하여 리스트 상태 유지
3. 마무리하며
Flutter로 커플 앱을 개발하는 과정에서 많은 기술적 도전을 경험했다.
특히 Riverpod 상태 관리, API 캐싱, Google Maps + Kakao API 연동, 성능 최적화 등의 이슈를 해결하면서 Flutter 개발에 대한 이해가 깊어졌다.
🚀 다음 목표:
1. Riverpod 심화 학습 (AsyncNotifier, FutureProvider)
2. API 요청 최적화 및 데이터 캐싱 고도화
3. Google Maps 기능 강화 및 UI 개선
이번 회고를 바탕으로 앞으로 더 최적화된 Flutter 개발을 할 수 있도록 노력해야겠다.
반응형
'1인 개발 > myapp' 카테고리의 다른 글
Google Map에서 현위치로 지도 이동 로직 개선 (0) | 2025.02.26 |
---|---|
[코드개선] MVVM 디자인 패턴의 잘못된 적용 개선하기 - kakao API요청 시 (0) | 2025.02.26 |