내일배움캠프 9일차

임클·2025년 3월 13일

내일배움캠프

목록 보기
9/44
post-thumbnail

일정

SwiftUI에서 싱글톤 패턴과 @EnvironmentObject의 차이점

📌 싱글톤 패턴이란?

싱글톤(Singleton) 패턴은 앱 전역에서 하나의 인스턴스를 공유하는 디자인 패턴입니다.

✅ 싱글톤 패턴을 class로 구현하는 이유

Swift에서 struct는 값 타입(Value Type)이고, class는 참조 타입(Reference Type)입니다. 싱글톤은 하나의 인스턴스를 유지하는 것이 핵심이므로, class를 사용해야 올바른 싱글톤이 됩니다.

⭕ 올바른 싱글톤 구현 (클래스 기반)

class CoreDataManager {
    static let shared = CoreDataManager() // 싱글톤 인스턴스
    private init() { } // 외부에서 인스턴스 생성 방지

    var data: [String] = []
}

// 사용 예시
CoreDataManager.shared.data.append("Hello")
print(CoreDataManager.shared.data) // ["Hello"]

❌ 잘못된 싱글톤 구현 (구조체 기반)

struct CoreDataManager {
    static var shared = CoreDataManager()
    var data: [String] = []
}

// 새로운 인스턴스 생성 (값 복사)
var newManager = CoreDataManager.shared
newManager.data.append("World")

print(CoreDataManager.shared.data) // ["Hello"] (변경 안됨!)
print(newManager.data) // ["Hello", "World"]

구조체 기반 싱글톤은 shared를 복사할 때마다 새로운 인스턴스가 생기므로, 싱글톤의 의미가 사라집니다.


📌 SwiftUI에서 싱글톤이 필수가 아닐 수도 있는 이유

SwiftUI는 선언형 UI 프레임워크로, 데이터 흐름을 @StateObject, @EnvironmentObject, @Environment를 활용하여 관리할 수 있습니다.

즉, 싱글톤을 직접 사용하지 않아도 데이터를 전역으로 공유할 수 있습니다.

📌 NSPersistentContainer를 SwiftUI에서 공유하는 방법

import SwiftUI
import CoreData

struct PersistenceController {
    static let shared = PersistenceController()

    let container: NSPersistentContainer

    init() {
        container = NSPersistentContainer(name: "MyModel")
        container.loadPersistentStores { _, error in
            if let error = error {
                fatalError("Unresolved error \(error)")
            }
        }
    }
}

위 코드는 struct로 싱글톤처럼 보이지만, 실제로 싱글톤 역할을 하는 것은 container(NSPersistentContainer)입니다.

📌 @Environment를 활용한 CoreData 공유

@main
struct MyApp: App {
    let persistenceController = PersistenceController.shared

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
        }
    }
}

이렇게 하면 PersistenceController.shared를 직접 사용하지 않아도 @Environment(\.managedObjectContext)를 통해 데이터 공유가 가능합니다.


📌 싱글톤 vs @EnvironmentObject 차이점

싱글톤 (Singleton)@EnvironmentObject
데이터 저장 위치앱 전역 인스턴스SwiftUI의 Environment
라이프사이클앱이 실행되는 동안 유지뷰 계층이 유지되는 동안 유지
다중 인스턴스 가능 여부불가능 (항상 하나)가능 (뷰마다 다를 수 있음)
예제UserManager.shared@EnvironmentObject var userManager: UserManager
사용 방식UserManager.shared.usernameuserManager.username

📌 @EnvironmentObject의 사용 예시

class UserManager: ObservableObject {
    @Published var username: String = "Guest"
}

struct ContentView: View {
    @EnvironmentObject var userManager: UserManager

    var body: some View {
        Text("Hello, \(userManager.username)!")
    }
}
@main
struct MyApp: App {
    @StateObject var userManager = UserManager()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(userManager)
        }
    }
}

@EnvironmentObject를 사용하면 싱글톤 없이도 데이터 공유가 가능하며, SwiftUI의 뷰 계층과 자연스럽게 연동됩니다.


📌 언제 싱글톤을 쓰고, 언제 @EnvironmentObject를 써야 할까?

싱글톤을 사용해야 하는 경우

  • Core Data 같이 앱 전체에서 공유해야 하는 데이터
  • 네트워크 관리 클래스 (ex: APIClient)
  • 로그인 관리 클래스 (ex: AuthManager)
  • 앱 설정 저장 (UserDefaults 기반 데이터)

@EnvironmentObject를 사용해야 하는 경우

  • 뷰 간 데이터 공유 (ex: 유저 상태, UI 상태)
  • 뷰 계층이 유지되는 동안만 필요한 데이터
  • SwiftUI와 자연스럽게 연동되는 데이터

✅ 결론

SwiftUI에서 싱글톤을 완전히 배제할 필요는 없지만, 꼭 필요하지 않다면 @EnvironmentObject 같은 SwiftUI 전용 데이터 흐름을 활용하는 것이 좋습니다.

Core Data, API 클라이언트 같은 글로벌 데이터는 싱글톤이 적합하고, UI 상태나 유저 정보 같은 뷰 관련 데이터는 @EnvironmentObject가 더 적합합니다.

💡 즉, 사용 목적에 따라 적절한 방식을 선택하는 것이 중요합니다!

0개의 댓글