왜: 디코딩된 비트맵의 과도한 보존으로 피크 메모리 증가. 전역 상한/만료 설정과 시스템 이벤트 연동으로 안정화 필요. 무엇(`SodaLiveApp.swift`): - `ImageCache.default` 구성 - 메모리: `totalCostLimit=120MB`, `countLimit=200`, `expiration=300s` - 디스크: `sizeLimit=500MB` - 훅 추가 - `didReceiveMemoryWarning` → `clearMemoryCache()` - `didEnterBackground` → `cleanExpiredMemoryCache()` 검증: 앱 기동/백그라운드/포어그라운드 전환 플로우 정상, 빌드 성공.
		
			
				
	
	
		
			77 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Swift
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Swift
		
	
	
	
	
	
//
 | 
						|
//  SodaLiveApp.swift
 | 
						|
//  SodaLive
 | 
						|
//
 | 
						|
//  Created by klaus on 2023/08/09.
 | 
						|
//
 | 
						|
 | 
						|
import SwiftUI
 | 
						|
import Kingfisher
 | 
						|
 | 
						|
import FBSDKCoreKit
 | 
						|
import AppsFlyerLib
 | 
						|
 | 
						|
@main
 | 
						|
struct SodaLiveApp: App {
 | 
						|
    
 | 
						|
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
 | 
						|
    
 | 
						|
    @ObservedObject var viewModel = AppViewModel()
 | 
						|
    
 | 
						|
    @StateObject var canPgPaymentViewModel = CanPgPaymentViewModel()
 | 
						|
    
 | 
						|
    init() {
 | 
						|
        configureImageCache()
 | 
						|
    }
 | 
						|
    
 | 
						|
    private func configureImageCache() {
 | 
						|
        // Kingfisher 전역 캐시 상한 설정
 | 
						|
        let cache = ImageCache.default
 | 
						|
        // 총 메모리 비용(바이트). 이미지 1장이 수 MB 수준이므로 80~150MB 범위 권장
 | 
						|
        cache.memoryStorage.config.totalCostLimit = 120 * 1024 * 1024
 | 
						|
        // 객체 개수 제한(옵션)
 | 
						|
        cache.memoryStorage.config.countLimit = 200
 | 
						|
        // 메모리 만료 정책(옵션)
 | 
						|
        cache.memoryStorage.config.expiration = .seconds(300)
 | 
						|
        // 디스크 캐시 용량 제한(옵션)
 | 
						|
        cache.diskStorage.config.sizeLimit = 500 * 1024 * 1024
 | 
						|
    }
 | 
						|
    
 | 
						|
    var body: some Scene {
 | 
						|
        WindowGroup {
 | 
						|
            ContentView(canPgPaymentViewModel: canPgPaymentViewModel)
 | 
						|
                .onReceive(NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)) { _ in
 | 
						|
                    CreatorCommunityMediaPlayerManager.shared.pauseContent()
 | 
						|
                    // 백그라운드 전환 시 메모리 캐시 정리
 | 
						|
                    ImageCache.default.cleanExpiredMemoryCache()
 | 
						|
                }
 | 
						|
                .onReceive(NotificationCenter.default.publisher(for: UIApplication.didReceiveMemoryWarningNotification)) { _ in
 | 
						|
                    // 메모리 경고 수신 시 캐시 즉시 해제
 | 
						|
                    ImageCache.default.clearMemoryCache()
 | 
						|
                }
 | 
						|
                .onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
 | 
						|
                    UIApplication.shared.applicationIconBadgeNumber = 0
 | 
						|
                    AppsFlyerLib.shared().start()
 | 
						|
                    
 | 
						|
                    if !AppState.shared.alreadyUpdatedMarketingInfo {
 | 
						|
                        viewModel.fetchAndUpdateIdfa()
 | 
						|
                        viewModel.getMemberInfo()
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                .onOpenURL { url in
 | 
						|
                    DEBUG_LOG("I have received a URL through a custom scheme! \(url.absoluteString)")
 | 
						|
                    
 | 
						|
                    if let comps = URLComponents(url: url, resolvingAgainstBaseURL: false),
 | 
						|
                        url.scheme?.lowercased() == APPSCHEME.lowercased(),
 | 
						|
                       comps.host?.lowercased() == "payverse",
 | 
						|
                       comps.path.lowercased() == "/result" {
 | 
						|
                        canPgPaymentViewModel.handleVerifyOpenURL(url)
 | 
						|
                    } else {
 | 
						|
                        ApplicationDelegate.shared.application(UIApplication.shared, open: url, options: [:])
 | 
						|
                        AppsFlyerLib.shared().handleOpen(url)
 | 
						|
                    }
 | 
						|
                }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |