[머릿말]
앱에서 필요한 데이터를 저장하기 위해 사용하는 두 개념에 대해 접하게 되었다. 데이터를 저장하는 일은 필수적이므로 자주 찾아보게 될 것 같아 글로 남겨놓고자 한다.
@SceneStorage와 @AppStorage는 모두 프로퍼티 래퍼(Property wrapper)다. 이는 SwiftUI가 데이터를 저장할 목적으로 제공한다. 저장할 데이터에 대한 String 타입의 key 값을 통해 데이터를 구분짓는다.
우리가 사용하는 앱은 종료되더라도 데이터는 보존된다. 이는 두 프로퍼티 래퍼를 사용하여 구현해볼 수 있다.
⦿ 두 프로퍼티 래퍼를 사용하지 않았을 때는?
두 프로퍼티 래퍼를 사용하지 않은 경우, 앱이 종료되면 데이터는 그 즉시 소멸된다. 간단하게 회원가입 화면을 통해 확인해보자. 아래 코드는 SceneStorage와 AppStorage를 다룰 때도 동일하게 사용될 예정이다.
import SwiftUI
struct ContentView: View {
@State var name: String = ""
@State var phone_number: String = ""
var body: some View {
VStack {
Text("회원가입")
.font(.largeTitle)
.fontWeight(.black)
.padding(10)
Form {
Section(header: Text("이름")) {
TextEditor(text: $name)
}
Section(header: Text("휴대전화")) {
HStack {
TextEditor(text: $phone_number)
}
}
}
}
}
}
#Preview {
ContentView()
}
위 예제를 통해 앱이 종료되고 다시 시작되는 경우 입력했던 데이터가 사라지는 것을 확인할 수 있다.
이를 위해 @SceneStorage와 @AppStorage를 사용해볼 수 있다.
⦿ @SceneStorage
공식 문서에서의 내용은 다음과 같다.
"지속되는 각 장면별 저장소에 읽거나 쓰는 프로퍼티 래퍼"
장면별 저장소..? 정확히 감이 잡히지 않을 수 있다. 이는 말 그대로 각 장면별 저장소를 뜻하는데, iPadOS, macOS처럼 다중 창(multi-windowing) 플랫폼에서 동일한 앱을 여러개 실행하는 경우 각각의 앱은 서로 다른 저장소에 데이터를 저장하게 된다.
아래 예제는 위에서 본 예제에서 프로퍼티 래퍼를 @Scene에서 @SceneStorage(_:)로 변경한 것이다.
import SwiftUI
struct ContentView: View {
@SceneStorage("name") var name: String = ""
@SceneStorage("phone_number") var phone_number: String = ""
var body: some View {
VStack {
Text("회원가입")
.font(.largeTitle)
.fontWeight(.black)
.padding(10)
Form {
Section(header: Text("이름")) {
TextEditor(text: $name)
}
Section(header: Text("휴대전화")) {
HStack {
TextEditor(text: $phone_number)
}
}
}
}
}
}
#Preview {
ContentView()
}
이제 앱을 재시작하더라도 입력했던 데이터가 사라지지 않게 되었다.
❖ iPad에서 앱을 여러개 실행하는 경우 ❖
앞서 언급했던 것처럼 멀티 윈도우 환경의 iPad에서 같은 앱을 실행시켜 보았다. 서로 같은 앱, 같은 화면임에도 불구하고 데이터가 공유되지 않는 것을 확인할 수 있다. 곧 다룰 @AppStorage는 같은 앱이면 데이터가 공유된다.
⦿ @AppStorage
공식 문서에서의 내용은 다음과 같다.
"UserDefaults의 값을 반영하고 해당 사용자 기본값의 값 변경에 대한 보기를 무효화하는 속성 래퍼 유형"
"값 변경에 대한 보기를 무효화한다"가 무슨 말이지... 나중에 깨닫게 되면 다시 수정해야겠다...
AppStorage는 iOS에서 오랫동안 사용된 UserDefaults를 기반으로 만들어졌다. UserDefault란 key-value 쌍으로 앱에 저장되는 소량의 데이터(로그인 정보, 환경 설정 등)를 저장할 때 사용하는 것이다.
이는 앞서 본 SceneStorage와는 달리 앱별로 데이터가 저장된다. 즉, 같은 앱이라면 데이터가 공유된다는 것이다. 앱을 종료하고 다시 시작했을 때 데이터가 보존되는 것은 위 예제와 동일하므로 생략하고, iPad에서 2개의 앱을 띄워본 결과를 확인해보겠다.
아래 예제는 위 코드에서 @SceneStorage를 @AppStorage로 바꾼 것이다.
import SwiftUI
struct ContentView: View {
@AppStorage("name") var name: String = ""
@AppStorage("phone_number") var phone_number: String = ""
var body: some View {
VStack {
Text("회원가입")
.font(.largeTitle)
.fontWeight(.black)
.padding(10)
Form {
Section(header: Text("이름")) {
TextEditor(text: $name)
}
Section(header: Text("휴대전화")) {
HStack {
TextEditor(text: $phone_number)
}
}
}
}
}
}
#Preview {
ContentView()
}
이처럼 AppStorage는 동일한 앱이라면 데이터가 같은 저장소에 저장되게 된다.
끝!
'[Programming Language] > [SwiftUI]' 카테고리의 다른 글
[SwiftUI] 앱 아이콘(Icon) 설정 방법 (1) | 2024.10.15 |
---|---|
[SwiftUI] TabView란? 사용 예시, 배경색 및 아이템 색 변경 등 (0) | 2024.10.14 |
[SwiftUI] Deprecated 되어버린 cornerRadius를 대체할 방법 (2) | 2024.10.13 |
[SwiftUI] Deprecated된 tabItem(_:)을 대신하여 Tab()을 사용할 수 있다 (5) | 2024.10.06 |
[SwiftUI] OutlineGroup과 DisclosureGroup의 차이점 (4) | 2024.10.05 |