import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter_localizations/flutter_localizations.dart'; import 'models/subscription_model.dart'; import 'models/category_model.dart'; import 'providers/subscription_provider.dart'; import 'providers/app_lock_provider.dart'; import 'providers/notification_provider.dart'; import 'screens/main_screen.dart'; import 'screens/app_lock_screen.dart'; import 'services/notification_service.dart'; import 'providers/category_provider.dart'; import 'providers/locale_provider.dart'; import 'l10n/app_localizations.dart'; import 'theme/app_theme.dart'; import 'screens/splash_screen.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'dart:io' show Platform; final GlobalKey navigatorKey = GlobalKey(); Future main() async { WidgetsFlutterBinding.ensureInitialized(); // 구글 모바일 광고 SDK 초기화 (웹이 아니고, Android/iOS에서만) if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) { await MobileAds.instance.initialize(); } // 앱 시작 시 이미지 캐시 관리 try { // 메모리 이미지 캐시는 유지하지만 필요한 경우 삭제할 수 있도록 준비 final cache = PaintingBinding.instance.imageCache; // 오래된 디스크 캐시 파일만 지우기 (새로운 것은 유지) await DefaultCacheManager().emptyCache(); print('이미지 캐시 관리 초기화 완료'); } catch (e) { print('캐시 초기화 오류: $e'); } // Hive 초기화 await Hive.initFlutter(); Hive.registerAdapter(SubscriptionModelAdapter()); Hive.registerAdapter(CategoryModelAdapter()); await Hive.openBox('subscriptions'); await Hive.openBox('categories'); final appLockBox = await Hive.openBox('app_lock'); // 알림 서비스를 가장 먼저 초기화 await NotificationService.init(); final subscriptionProvider = SubscriptionProvider(); final categoryProvider = CategoryProvider(); final localeProvider = LocaleProvider(); final notificationProvider = NotificationProvider(); await subscriptionProvider.init(); await categoryProvider.init(); await localeProvider.init(); await notificationProvider.init(); // NotificationProvider에 SubscriptionProvider 연결 (알림 재예약용) // SRP 원칙에 따라 다른 Provider 객체를 명시적으로 주입 notificationProvider.setSubscriptionProvider(subscriptionProvider); // 별도의 비동기 함수로 알림 관련 초기화 오류 처리 Future.delayed(Duration.zero, () { try { if (notificationProvider.isPaymentEnabled) { // 백그라운드에서 비동기적으로 알림 설정 업데이트 NotificationService.reschedulAllNotifications( subscriptionProvider.subscriptions); } } catch (e) { debugPrint('알림 초기 설정 중 오류 발생: $e'); } }); runApp( MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => subscriptionProvider), ChangeNotifierProvider(create: (_) => categoryProvider), ChangeNotifierProvider(create: (_) => AppLockProvider(appLockBox)), ChangeNotifierProvider(create: (_) => notificationProvider), ChangeNotifierProvider(create: (_) => localeProvider), ], child: const SubManagerApp(), ), ); } class SubManagerApp extends StatelessWidget { const SubManagerApp({super.key}); @override Widget build(BuildContext context) { return Consumer( builder: (context, localeProvider, child) { return MaterialApp( title: 'SubManager', debugShowCheckedModeBanner: false, theme: AppTheme.lightTheme, locale: localeProvider.locale, localizationsDelegates: const [ AppLocalizationsDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: const [ Locale('en'), Locale('ko'), ], navigatorKey: navigatorKey, home: const SplashScreen(), ); }, ); } }