ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SwiftUI - Passing EnvironmentObject
    SwiftUI 2022. 3. 17. 02:31

    SwiftUI 에서 EnvironmentObject 는 매우.. 강력하다

     

    import SwiftUI
    
    @main
    struct DeeepMemoApp: App {
    
        
        @Environment(\.scenePhase) var scenePhase
        
        let memoEditVM = MemoEditViewModel()
        let folderEditVM = FolderEditViewModel()
        let folderOrder = FolderOrder()
        let memoOrder = MemoOrder()
        
        var body: some Scene {
    
            return WindowGroup {
                HomeView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
                .environmentObject(memoEditVM)
                .environmentObject(folderEditVM)
                .environmentObject(folderOrder)
                .environmentObject(memoOrder)
            }
        }
    }

    @main 이 선언되어있는 File 에서 EnvironmentObject 를 만들어준 후 View 에 전달하면 그 View 와 하위에 속한 모든 View 에서 해당 EnvironmentObject 를 사용할 수 있다.

     

    위 View 는 앱이 시작된 후 실행되어 앱 내의 어떠한 View 로 이동해도 사라지지 않은 상태로 있기 때문에, 다른 View 에서 EnvironmentObject 를 전달하는 것과는 다르다...

     

    실제로 이렇게 하기 전에는 하단 View 에서 더 아래에 있는 View 에 EnvironmentObject 를 전달했었는데, 처음 선언한 View 가 다른 View 로 이동할 때 사라지므로, 이때 Object 가 제대로 전달되지 않는 경우가 있었다. 

     

    하위에서 더 하위로 갈 때마다 Object 를 전달해주면 잘 작동하지만, 그러면 코드가 매우매우 못생겨지고, View 를 옮길 때마다 전달해주어야 하기 때문에, @main 이 선언된 View 에서 전달하는 것을 적극 권한다. (Combine 을 공부하면서 깨달았다.)

     

     

     

     

     

     

    @main 은 이것 외에 ScenePhase 를 관리할 때도 유용하게 쓰인다.

    import SwiftUI
    import CoreData
    
    @main
    struct DeeepMemoApp: App {
    
        let persistenceController = PersistenceController.shared
        @Environment(\.scenePhase) var scenePhase
        
           ...
        
        var body: some Scene {
        
            return WindowGroup {
                HomeView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
                ...
            }
            
            
            
            .onChange(of: scenePhase) { newScenePhase in
                switch newScenePhase {
                case .background :
                    print("Scene is in background")
                    try? persistenceController.container.viewContext.save()
                case .inactive:
                    try? persistenceController.container.viewContext.save()
                    print("Scene is in inactive")
                case .active:
                    print("Scene is in active")
                @unknown default:
                    try? persistenceController.container.viewContext.save()
                    print("Scene is in default")
                }
            }
        }
    }

    ScenePhase 란, 현재 앱이 어떤 상태에 있는지를 나타내준다. 

    active, inactive, background 등이 있고, 

    active 가 현재 앱을 사용중일 때의 상태이다. 

     

    UIKit 에서의 SceneDelegate 와 대응하는 역할을 맡는다고 보면 되겠다. 

    CoreData 를 사용하고 있으므로, scenePhase 가 active 외의 상태로 변할 때 저장하도록 하였다. 

    'SwiftUI' 카테고리의 다른 글

    SwiftUI - Action sheet  (0) 2022.01.13
    SwiftUI - Handle Binding value in Preview  (0) 2022.01.13
    NavigationView in SwiftUI  (0) 2022.01.11
Designed by Tistory.