SwiftUI

SceneStorage

Phililip
728x90

안녕하세요.

 

이번에는 SwiftUI의 SceneStorage에 대해 알아볼게요.

 

 


 

# 1. Overview

SceneStorage는 Scene 고유 저장소에 읽고 쓰고 할 수 있는 프로퍼티 래퍼입니다.

 

상태를 복구하고 싶을 때, SceneStorage를 사용합니다.

 

State와 유사하지만, SceneStorage는 동일 Scene에서는 그 값을 공유합니다.

 

다른 Scene들 간에는 SceneStorage 데이터는 공유되지 않습니다.

 

 

주의할 점이 있는데요, SceneStorage를 관리하는 시스템은 언제 어떻게 데이터를 지속시킬 건지 보장해주지 않아요.

 

그리고 SceneStorage에 저장할 데이터가 무거울 경우(ex. model data) 성능에 안 좋을 수 있으니 가벼운 데이터만 사용해주세요.

 

또한, Scene이 제거된 경우 데이터도 함께 제거되니 SceneStorage에 민감한 데이터는 사용하지 말아 주세요!

 

 

SceneStorage를 간단하게 다시 정리해보자면,

 

Scene 별로 가지고 있는 저장소에 접근해서 읽고 쓸 수 있고

 

Scene이 유지되는 동안 동일 Scene에서는 데이터를 공유해서 사용이 가능하다는 것입니다.

 

 

 

# 2. SceneStorage는 언제 사용하는지?

그럼 SceneStorage는 언제 사용하면 좋을까요?

 

위에서 잠깐 언급하긴 했어요.

 

상태를 복구하고 싶을 때, SceneStorage를 사용합니다.

 

 

상태를 복구... 라는 말이 좀 와닿지 않을 수 있는데 특정 상황을 예를 들어서 설명할게요.

 

 

어떤 앱을 들어가서 막 어떤 작업을 하다가 잠시 다른 일을 하려고 앱을 백그라운드로 내리는 상상을 해볼게요.

 

그러다 한참 뒤에 작업을 마저 하려고 앱을 다시 켰을 때 저희는 2가지 상황을 보게 될 것입니다.

 

1. 백그라운드로 내린 상태 그대로 다시 앱이 올라옴.
2. 시스템이 앱을 재실행 시킴.

 

문제는 2번째 경우예요. 시스템이 앱을 재실행시키면 그동안 작업했던 것들이 전부 날아가는 상황이 발생해요.

 

이때 SceneStorage를 사용하면, 앱이 재실행되더라도 그동안 작업했던 것(상태)들이 복구시켜줄 수 있다는 것이죠.

 

이해가 좀 되실까요??ㅎㅎㅎ

 

직접 예를 들어서 다시 확인해볼게요.

 

 

 

# 3. 사용 예시

일단 SceneStorage를 사용하지 않을 경우, 어떤 일이 벌어지는지부터 살펴볼게요.

(SceneStorage 대신 State를 사용했습니다.)

 

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink {
                TextEditorView()
            } label: {
                Text("TextEditor")
            }
            .navigationTitle("NavigationView")

        }
    }
}

struct TextEditorView: View {
    @State private var text = ""
    var body: some View {
        TextEditor(text: $text)
            .frame(width: 300, height: 200)
            .border(.black)
    }
}

 

 

 

 

TextEditor에 뭔가를 입력하고 백그라운드로 내린 다음, Xcode 빌드를 다시 해볼게요.

 

 

앱이 재실행되면서, 그전에 TextEditor에 입력한 정보가 다 날아갔죠??ㅠㅠ

 

 

이번에는 SceneStorage를 사용해서 정보를 복구시켜볼게요.

 

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink {
                TextEditorView()
            } label: {
                Text("TextEditor")
            }
            .navigationTitle("NavigationView")
        }
    }
}

struct TextEditorView: View {
    @SceneStorage("text") private var text = ""    ✅
    
    var body: some View {
        TextEditor(text: $text)
            .frame(width: 300, height: 200)
            .border(.black)
    }
}

 

 

다시 실행시켜도 전에 입력한 값이 유지된 것이 보이시나요??? 👍 👍 👍

 

 

SceneStorage는 Scene 하나하나가 별도의 저장소를 가지고 있다고 말씀드린 거 기억하시나요??

 

그 말은 multi-scene을 지원하는 iPadOS나 macOS에서 앱을 재실행시키면, Scene 별로 상태가 따로따로 복구된다는 의미예요.

 

iPad에서 직접 확인해볼까요???ㅎㅎㅎㅎ

 

 

Scene 별로 잘 복구가 되었네요!!ㅎㅎㅎ

 

 

만약, 앱이 백그라운드 상태가 아닌 앱을 종료했다가 다시 켰을 때도 상태가 유지되고 싶다면 AppStorage를 사용해주세요.

 

 

 


 

 

이번 글은 여기서 마무리.

 

 

 

반응형

'SwiftUI' 카테고리의 다른 글

Gesture  (0) 2022.04.01
__printChanges  (0) 2022.03.23
Canvas 뷰를 통한 성능 향상  (0) 2022.03.14
cornerRadius  (0) 2022.03.13
SwiftUI에서 testable 한 코드 만들기  (0) 2022.03.05