Files
lunchpick/lib/core/network
JiWoong Sul 85fde36157 feat: 초기 프로젝트 설정 및 LunchPick 앱 구현
LunchPick(오늘 뭐 먹Z?) Flutter 앱의 초기 구현입니다.

주요 기능:
- 네이버 지도 연동 맛집 추가
- 랜덤 메뉴 추천 시스템
- 날씨 기반 거리 조정
- 방문 기록 관리
- Bluetooth 맛집 공유
- 다크모드 지원

기술 스택:
- Flutter 3.8.1+
- Riverpod 상태 관리
- Hive 로컬 DB
- Clean Architecture

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 19:03:28 +09:00
..

네트워크 모듈 사용 가이드

개요

이 네트워크 모듈은 네이버 단축 URL 처리와 로컬 API 검색을 위한 통합 솔루션을 제공합니다. Dio 기반으로 구축되어 재시도, 캐싱, 로깅 등의 기능을 제공합니다.

주요 기능

  1. 네이버 단축 URL 리다이렉션 처리
  2. HTML 스크래핑으로 식당 정보 추출
  3. 네이버 로컬 검색 API 통합
  4. 자동 재시도 및 에러 처리
  5. 응답 캐싱으로 성능 최적화
  6. 네트워크 불안정 상황 대응

사용 방법

1. 네이버 지도 URL에서 식당 정보 추출

import 'package:lunchpick/data/datasources/remote/naver_search_service.dart';

final searchService = NaverSearchService();

try {
  // 일반 네이버 지도 URL
  final restaurant = await searchService.getRestaurantFromUrl(
    'https://map.naver.com/p/restaurant/1234567890',
  );
  
  // 단축 URL도 자동 처리
  final restaurant2 = await searchService.getRestaurantFromUrl(
    'https://naver.me/abc123',
  );
  
  print('식당명: ${restaurant.name}');
  print('카테고리: ${restaurant.category}');
  print('주소: ${restaurant.roadAddress}');
} catch (e) {
  print('오류 발생: $e');
}

2. 키워드로 주변 식당 검색

// 현재 위치 기반 검색
final restaurants = await searchService.searchNearbyRestaurants(
  query: '파스타',
  latitude: 37.5666805,
  longitude: 126.9784147,
  maxResults: 20,
  sort: 'random', // 정확도순 정렬 (기본값)
);

for (final restaurant in restaurants) {
  print('${restaurant.name} - ${restaurant.roadAddress}');
}

3. 식당 상세 정보 검색

// 식당 이름과 주소로 상세 정보 검색
final details = await searchService.searchRestaurantDetails(
  name: '맛있는 한식당',
  address: '서울 중구 세종대로',
  latitude: 37.5666805,
  longitude: 126.9784147,
);

if (details != null) {
  print('영업시간: ${details.businessHours}');
  print('전화번호: ${details.phoneNumber}');
}

4. 네트워크 에러 처리

import 'package:lunchpick/core/errors/network_exceptions.dart';

try {
  final restaurant = await searchService.getRestaurantFromUrl(url);
} on ConnectionTimeoutException {
  // 연결 타임아웃
  showSnackBar('네트워크 연결이 느립니다. 다시 시도해주세요.');
} on NoInternetException {
  // 인터넷 연결 없음
  showSnackBar('인터넷 연결을 확인해주세요.');
} on ApiKeyException {
  // API 키 설정 필요
  showSnackBar('네이버 API 키를 설정해주세요.');
} on NaverMapParseException catch (e) {
  // 파싱 오류
  showSnackBar('식당 정보를 가져올 수 없습니다: ${e.message}');
} catch (e) {
  // 기타 오류
  showSnackBar('알 수 없는 오류가 발생했습니다.');
}

설정

API 키 설정

네이버 로컬 검색 API를 사용하려면 API 키가 필요합니다:

  1. 네이버 개발자 센터에서 애플리케이션 등록
  2. Client ID와 Client Secret 발급
  3. lib/core/constants/api_keys.dart 파일에 키 입력:
class ApiKeys {
  static const String naverClientId = 'YOUR_CLIENT_ID';
  static const String naverClientSecret = 'YOUR_CLIENT_SECRET';
}

네트워크 설정 커스터마이징

lib/core/network/network_config.dart에서 타임아웃, 재시도 횟수 등을 조정할 수 있습니다:

class NetworkConfig {
  static const int connectTimeout = 15000; // 15초
  static const int maxRetries = 3; // 최대 3회 재시도
  static const Duration cacheMaxAge = Duration(minutes: 15); // 15분 캐싱
}

아키텍처

lib/
├── core/
│   ├── errors/
│   │   ├── app_exceptions.dart     # 앱 전체 예외 클래스들
│   │   ├── data_exceptions.dart    # 데이터 레이어 예외
│   │   └── network_exceptions.dart # 네트워크 예외
│   └── network/
│       ├── network_client.dart      # Dio 기반 HTTP 클라이언트
│       ├── network_config.dart      # 네트워크 설정
│       └── interceptors/
│           ├── retry_interceptor.dart    # 재시도 로직
│           └── logging_interceptor.dart  # 로깅
├── data/
│   ├── api/
│   │   └── naver_api_client.dart   # 네이버 API 클라이언트
│   └── datasources/
│       └── remote/
│           ├── naver_map_parser.dart      # HTML 파싱
│           └── naver_search_service.dart  # 통합 검색 서비스

주의사항

  1. API 키 보안: API 키는 절대 Git에 커밋하지 마세요. .gitignore에 추가하세요.
  2. 요청 제한: 네이버 API는 일일 요청 제한이 있습니다. 과도한 요청을 피하세요.
  3. 캐싱: 동일한 요청은 15분간 캐싱됩니다. 실시간 정보가 필요한 경우 useCache: false 옵션을 사용하세요.
  4. 웹 환경: 웹에서는 CORS 제한으로 인해 프록시 서버를 통해 요청합니다.

문제 해결

CORS 에러 (웹)

웹 환경에서 CORS 에러가 발생하면 프록시 서버가 일시적으로 사용 불가능한 상태일 수 있습니다. 잠시 후 다시 시도하거나 직접 입력 기능을 사용하세요.

타임아웃 에러

네트워크가 느린 환경에서는 NetworkConfig의 타임아웃 값을 늘려보세요.

API 키 에러

API 키가 올바르게 설정되었는지 확인하고, 네이버 개발자 센터에서 API 사용 권한이 활성화되어 있는지 확인하세요.