Skip to content

Commit

Permalink
Create 240820_SwiftUI,_Property_Wrapper.md
Browse files Browse the repository at this point in the history
  • Loading branch information
leeari95 committed Aug 20, 2024
1 parent ce1857f commit 57ac0d2
Showing 1 changed file with 210 additions and 0 deletions.
210 changes: 210 additions & 0 deletions Sources/AriNote/TIL.docc/SwiftUI/240819_SwiftUI,_Property_Wrapper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
# 240819 SwiftUI Property Wrapper

SwiftUI의 ν”„λ‘œνΌν‹° 래퍼 μ’…λ₯˜ λŒ€ν•΄μ„œ κ°„λ‹¨νžˆ μ•Œμ•„λ³΄μž.

8μ›” 19일 (μ›”)

# ν•™μŠ΅λ‚΄μš©

νšŒμ‚¬ ν”„λ‘œμ νŠΈ λ‚΄ 일뢀 화면을 SwiftUI와 Combine을 μ‚¬μš©ν•˜μ—¬ λ¦¬νŒ©ν† λ§μ„ μ§„ν–‰ν•΄λ³΄μ•˜λŠ”λ°, μ‚¬μš©ν•œ ν”„λ‘œνΌν‹° λž˜νΌμ— λŒ€ν•œ 이해도가 λΆ€μ‘±ν•œ 것 κ°™μ•„μ„œ μ•Œμ•„λ³΄μ•˜λ‹€.

## Property Wrapper

SwiftUIμ—μ„œ ν”„λ‘œνΌν‹° λž˜νΌλŠ” μƒνƒœ 관리λ₯Ό μ‰½κ²Œ ν•˜κ³  뷰와 데이터 κ°„μ˜ μƒν˜Έμž‘μš©μ„ κ°„λ‹¨ν•˜κ²Œ ν•  수 μžˆλ„λ‘ 도와쀀닀.

### `@State`

`@State`λŠ” SwiftUIμ—μ„œ 둜컬 λ·° μƒνƒœλ₯Ό κ΄€λ¦¬ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λœλ‹€. `@State`둜 μ„ μ–Έλœ λ³€μˆ˜λŠ” 변경될 λ•Œ λ§ˆλ‹€ ν•΄λ‹Ή λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” λ·°κ°€ λ‹€μ‹œ λ Œλ”λ§λœλ‹€.

* μ–Έμ œ μ‚¬μš©ν•΄μ•Ό ν• κΉŒ?
* λ·° λ‚΄λΆ€μ—μ„œλ§Œ μ‚¬μš©ν•˜λŠ” κ°„λ‹¨ν•œ μƒνƒœλ₯Ό 관리할 λ•Œ μ‚¬μš©ν•œλ‹€. 예λ₯Ό λ“€μ–΄, λ²„νŠΌμ˜ ν™œμ„±ν™” μƒνƒœ, ν† κΈ€ μƒνƒœ, ν…μŠ€νŠΈ ν•„λ“œμ˜ μž…λ ₯ κ°’ 등을 관리할 λ•Œ μ ν•©ν•˜λ‹€.
* λΆ€λͺ¨λ·°λ‚˜ μ™ΈλΆ€μ—μ„œ μ ‘κ·Όν•  ν•„μš”κ°€ μ—†μœΌλ©° λ·°κ°€ λ‹€μ‹œ λ Œλ”λ§λ  λ•Œλ§ˆλ‹€ ν•„μš”μ— 따라 μ—…λ°μ΄νŠΈ ν•˜κ²Œ λœλ‹€.

`@State`λŠ” λ·°κ°€ μ†Œλ©Έλ˜λ©΄ μƒνƒœλ„ ν•¨κ»˜ μ‚¬λΌμ§€λ―€λ‘œ 뷰의 생λͺ… 주기와 ν•¨κ»˜ μƒνƒœκ°€ μ΄ˆκΈ°ν™”λœλ‹€. λ”°λΌμ„œ μž₯기적인 μƒνƒœ μ €μž₯이 ν•„μš”ν•œ κ²½μš°μ—λŠ” @AppStorage, @SceneStorageλ₯Ό κ³ λ €ν•΄μ•Ό ν•œλ‹€.

### `@Binding`

`@Binding`은 λΆ€λͺ¨λ·°μ—μ„œ κ΄€λ¦¬ν•˜λŠ” μƒνƒœλ₯Ό μžμ‹λ·°λ‘œ μ „λ‹¬ν•˜μ—¬ μžμ‹λ·°μ—μ„œ μƒνƒœλ₯Ό μˆ˜μ •ν•  수 있게 ν•΄μ€€λ‹€. `@Binding`을 μ‚¬μš©ν•˜λ©΄ μžμ‹λ·°κ°€ λΆ€λͺ¨λ·°μ˜ μƒνƒœλ₯Ό 직접 μˆ˜μ •ν•  수 μžˆμ–΄ λ·° κ°„ μƒνƒœ 동기화가 κ°€λŠ₯ν•˜λ‹€.

* μ–Έμ œ μ‚¬μš©ν•΄μ•Ό ν• κΉŒ?
* λΆ€λͺ¨λ·°μ—μ„œ μ •μ˜λœ μƒνƒœλ₯Ό μžμ‹λ·°μ—μ„œ μ°Έμ‘°ν•˜κ³  μˆ˜μ •ν•  ν•„μš”κ°€ μžˆμ„ λ•Œ μ‚¬μš©ν•œλ‹€.
* 예λ₯Ό λ“€μ–΄ λΆ€λͺ¨λ·°μ—μ„œ κ΄€λ¦¬ν•˜λŠ” ν…μŠ€νŠΈ ν•„λ“œμ˜ 값을 μžμ‹λ·°μ—μ„œ νŽΈμ§‘ν•  수 μžˆλ„λ‘ ν•΄μ•Όν•  λ•Œ μ ν•©ν•˜λ‹€.

`@Binding`을 톡해 μžμ‹λ·°κ°€ μƒνƒœλ₯Ό μˆ˜μ •ν•  수 μžˆμ§€λ§Œ, λΆ€λͺ¨λ·°μ˜ μƒνƒœκ°€ μ˜ˆμƒμΉ˜ μ•Šκ²Œ 변경될 수 μžˆμœΌλ―€λ‘œ μ‹ μ€‘ν•˜κ²Œ 관리해야 ν•œλ‹€.
κ°„λ‹¨ν•œ μƒν™©μ—μ„œλŠ” `@State`만으둜 μΆ©λΆ„ν•  수 있으며, λ„ˆλ¬΄ λΉˆλ²ˆν•˜κ²Œ `@Binding`을 μ‚¬μš©ν•˜λ©΄ μ½”λ“œκ°€ λ³΅μž‘ν•΄μ§ˆ 수 μžˆμœΌλ‹ˆ μ£Όμ˜ν•΄μ•Ό ν•œλ‹€.



```swift
// ν•˜μœ„λ·°μ™€ μƒνƒœ 곡유 μ˜ˆμ‹œ
struct PlayerView: View {
var episode: Episode
@State private var isPlaying: Bool = false // Create the state here now.


var body: some View {
VStack {
Text(episode.title)
.foregroundStyle(isPlaying ? .primary : .secondary)
PlayButton(isPlaying: $isPlaying) // Pass a binding.
}
}
}

struct PlayButton: View {
@Binding var isPlaying: Bool // Play button now receives a binding.


var body: some View {
Button(isPlaying ? "Pause" : "Play") {
isPlaying.toggle()
}
}
}
```

### `@ObservedObject`

`@ObservedObject`λŠ” `ObservableObject` ν”„λ‘œν† μ½œμ„ μ€€μˆ˜ν•˜λŠ” 객체λ₯Ό κ΄€μ°°ν•˜κ³ , ν•΄λ‹Ή 객체의 μƒνƒœκ°€ 변경될 λ•Œλ§ˆλ‹€ λ·°λ₯Ό μžλ™μœΌλ‘œ μ—…λ°μ΄νŠΈ ν•œλ‹€.
주둜 λ·° λͺ¨λΈ νŒ¨ν„΄μ—μ„œ μ‚¬μš©λ˜λ©°, 뷰와 데이터 λ‘œμ§μ„ λΆ„λ¦¬ν•œλ‹€.

* μ–Έμ œ μ‚¬μš©ν•΄μ•Ό ν• κΉŒ?
* 뷰와 데이터 λ‘œμ§μ„ λΆ„λ¦¬ν•˜κ³  μ—¬λŸ¬ λ·°μ—μ„œ κ³΅μœ λ˜λŠ” μƒνƒœλ₯Ό 관리할 λ•Œ μ‚¬μš©ν•œλ‹€.
* 예λ₯Ό λ“€μ–΄ λ„€νŠΈμ›Œν¬ μš”μ²­μ˜ κ²°κ³Όλ₯Ό μ €μž₯ν•˜κ³  κ΄€λ¦¬ν•˜λŠ” λ·° λͺ¨λΈμ„ λ·°μ—μ„œ μ°Έμ‘°ν•  λ•Œ `@ObservedObject`λ₯Ό μ‚¬μš©ν•œλ‹€.
* 데이터 λͺ¨λΈμ΄λ‚˜ μ„œλΉ„μŠ€ 객체의 μƒνƒœ λ³€ν™”λ₯Ό λ·°μ—μ„œ κ°μ§€ν•˜κ³  μžλ™μœΌλ‘œ UIλ₯Ό μ—…λ°μ΄νŠΈν•΄μ•Ό ν•  λ•Œ μ‚¬μš©λœλ‹€.

`@ObservedObject`λŠ” λ·°κ°€ κ°•ν•œ μ°Έμ‘°λ₯Ό 가지지 μ•ŠμœΌλ―€λ‘œ λ·°κ°€ μ†Œλ©Έλ˜λ”λΌλ„ 객체가 ν•΄μ œλ˜μ§€ μ•ŠλŠ” λ©”λͺ¨λ¦¬ λˆ„μˆ˜μ— μ£Όμ˜ν•΄μ•Ό ν•œλ‹€. `@ObservedObject`둜 μ‚¬μš©λœ κ°μ²΄λŠ” λ‹€λ₯Έ κ³³μ—μ„œ κ°•ν•˜κ²Œ μ°Έμ‘°λ˜μ–΄μ•Ό ν•œλ‹€.
데이터가 자주 λ³€κ²½λ˜λŠ” 경우 μ μ ˆν•œ 동기화 없이 μ—¬λŸ¬ λ·°μ—μ„œ λ™μ‹œμ— μƒνƒœκ°€ μ—…λ°μ΄νŠΈλ˜λ©΄ 좩돌이 λ°œμƒν•  수 μžˆλ‹€.

`@ObservedObject`λŠ” `@State`와 λ‹€λ₯΄κ²Œ 클래슀 νƒ€μž…μ—μ„œ μ‚¬μš©λœλ‹€.

```swift
class DataModel: ObservableObject {
@Published var name = "Some Name"
@Published var isEnabled = false
}


struct MyView: View {
@StateObject private var model = DataModel()


var body: some View {
Text(model.name)
MySubView(model: model)
}
}


struct MySubView: View {
@ObservedObject var model: DataModel


var body: some View {
Toggle("Enabled", isOn: $model.isEnabled)
}
}
```

### `@Published`

`@Published`λŠ” `ObservableObject` ν”„λ‘œν† μ½œμ„ λ”°λ₯΄λŠ” 클래슀 λ‚΄μ—μ„œ νŠΉμ • ν”„λ‘œνΌν‹°κ°€ λ³€κ²½λ˜μ—ˆμ„ λ•Œ ν•΄λ‹Ή 변경을 μ•Œλ¦¬κ³  이λ₯Ό κ΄€μ°°ν•˜κ³  μžˆλŠ” λ·°κ°€ μžλ™μœΌλ‘œ μ—…λ°μ΄νŠΈλ  수 μžˆλ„λ‘ ν•΄μ€€λ‹€.

* μ–Έμ œ μ‚¬μš©ν•΄μ•Ό ν• κΉŒ?
* λ·° λͺ¨λΈ νŒ¨ν„΄μ—μ„œ `@ObservedObject`와 ν•¨κ»˜ μ‚¬μš©ν•˜μ—¬ λ·°κ°€ 데이터 λͺ¨λΈμ˜ νŠΉμ • ν”„λ‘œνΌν‹° 변경에 λ°˜μ‘ν•˜λ„λ‘ ν•  λ•Œ μ‚¬μš©ν•œλ‹€.
* 예λ₯Ό λ“€μ–΄ λ„€νŠΈμ›Œν¬ μ‘λ‹΅μ΄λ‚˜ μ‚¬μš©μž μž…λ ₯에 따라 λ™μ μœΌλ‘œ λ³€ν•˜λŠ” 데이터λ₯Ό 관리할 λ•Œ μœ μš©ν•˜λ‹€.

`@Published`둜 μ„ μ–Έλœ ν”„λ‘œνΌν‹°λŠ” 항상 λ·°λ₯Ό μ—…λ°μ΄νŠΈ ν•˜λ―€λ‘œ λΉˆλ²ˆν•œ 변경이 λ°œμƒν•˜λŠ” 경우 λΆˆν•„μš”ν•œ λ·° μ—…λ°μ΄νŠΈκ°€ λ°œμƒν•  수 μžˆλ‹€. λ”°λΌμ„œ μ„±λŠ₯ λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆμœΌλ―€λ‘œ κΌ­ ν•„μš”ν•œ κ²½μš°μ—λ§Œ `@Published`λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.
λ˜ν•œ `@Published`λŠ” 클래슀 νƒ€μž…μ˜ ν”„λ‘œνΌν‹°μ—λ§Œ μ‚¬μš©λ˜λ©° κ°’νƒ€μž…μ—μ„œλŠ” μ‚¬μš©ν•  수 μ—†λ‹€.

### `@StateObject`

`@StateObject`λŠ” SwiftUIμ—μ„œ μƒνƒœ 객체(ObservableObject)λ₯Ό κ΄€λ¦¬ν•˜λŠ” 데 μ‚¬μš©λ˜λŠ” ν”„λ‘œνΌν‹° λž˜νΌλ‹€. `@StateObject`λŠ” νŠΉμ • 뷰의 생λͺ… μ£ΌκΈ° λ™μ•ˆ 객체의 μƒνƒœλ₯Ό μœ μ§€ν•˜κ³ , 이 객체의 μƒνƒœκ°€ λ³€κ²½λ˜λ©΄ λ·°λ₯Ό λ‹€μ‹œ λ Œλ”λ§ν•œλ‹€. `@StateObject`λŠ” λ·°κ°€ 처음 μ΄ˆκΈ°ν™”λ  λ•Œ ν•œ 번만 객체λ₯Ό μƒμ„±ν•˜λ©°, λ·°κ°€ λ‹€μ‹œ 생성될 λ•Œλ„ λ™μΌν•œ 객체 μΈμŠ€ν„΄μŠ€λ₯Ό μ‚¬μš©ν•œλ‹€.

* μ–Έμ œ μ‚¬μš©ν•΄μ•Ό ν• κΉŒ?
* λ·°κ°€ μƒνƒœ 객체의 생λͺ… μ£ΌκΈ°λ₯Ό μ†Œμœ ν•˜κ³  관리해야 ν•  λ•Œ `@StateObject`λ₯Ό μ‚¬μš©ν•œλ‹€.
* 예λ₯Ό λ“€μ–΄, λ·°κ°€ νŠΉμ • 데이터 λͺ¨λΈμ˜ μƒνƒœλ₯Ό 직접 관리해야 ν•˜κ±°λ‚˜, λ·°κ°€ μ†Œλ©Έλ  λ•Œ μƒνƒœ 객체도 ν•¨κ»˜ μ†Œλ©Έλ˜μ–΄μ•Ό ν•˜λŠ” κ²½μš°μ— μ ν•©ν•˜λ‹€.

`@StateObject`λŠ” 뷰의 μ΄ˆκΈ°ν™” μ‹œμ μ— ν•œ 번만 객체λ₯Ό μƒμ„±ν•˜λ―€λ‘œ, `@StateObject`둜 μ„ μ–Έλœ κ°μ²΄λŠ” 뷰의 ꡬ쑰가 λ³€κ²½λ˜μ–΄λ„ λ™μΌν•œ μΈμŠ€ν„΄μŠ€κ°€ μœ μ§€λœλ‹€. λ§Œμ•½ λ·° κ³„μΈ΅μ˜ λ‹€λ₯Έ κ³³μ—μ„œ λ™μΌν•œ 객체λ₯Ό μ°Έμ‘°ν•˜λ €κ³  ν•˜λ©΄, `@ObservedObject`λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

같은 μƒνƒœ 객체λ₯Ό μ—¬λŸ¬ λ·°μ—μ„œ 관리해야 ν•  λ•ŒλŠ” `@StateObject`와 `@ObservedObject`λ₯Ό ν˜Όμš©ν•˜μ§€ μ•Šλ„λ‘ μ£Όμ˜ν•΄μ•Ό ν•œλ‹€. 객체의 생λͺ… 주기와 λ©”λͺ¨λ¦¬ 관리에 ν˜Όλž€μ„ μ΄ˆλž˜ν•  수 μžˆλ‹€.

`@StateObject`λŠ” SwiftUI 2.0μ—μ„œ λ„μž…λ˜μ—ˆμœΌλ©°, λ·°κ°€ 객체의 생λͺ… μ£ΌκΈ°λ₯Ό μ±…μž„μ Έμ•Ό ν•˜λŠ” μƒν™©μ—μ„œ 맀우 μœ μš©ν•˜λ‹€. 특히 λ·°κ°€ μƒνƒœ 객체λ₯Ό μ²˜μŒλΆ€ν„° μ†Œμœ ν•˜κ³  관리해야 ν•˜λŠ” λ³΅μž‘ν•œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μ€‘μš”ν•œ 역할을 ν•˜κ²Œ λœλ‹€.

`@StateObject`λŠ” 일반적으둜 λ·°κ°€ 처음 생성될 λ•Œ μ‚¬μš©ν•˜λŠ” 것이 μ’‹μœΌλ©°, 이미 μƒμ„±λœ μƒνƒœ 객체λ₯Ό λ‹€λ₯Έ λ·°μ—μ„œ μ‚¬μš©ν•  λ•ŒλŠ” `@ObservedObject`λ₯Ό μ‚¬μš©ν•œλ‹€.

>`@StateObject`λŠ” `@ObservedObject`와 λΉ„μŠ·ν•΄ λ³΄μ΄μ§€λ§Œ, μ€‘μš”ν•œ 차이점은 객체의 생λͺ… 주기와 μ΄ˆκΈ°ν™” 방식에 μžˆλ‹€.
>`@StateObject`λŠ” λ·°κ°€ μƒνƒœ 객체λ₯Ό μ†Œμœ ν•˜κ³  κ΄€λ¦¬ν•˜λŠ” 데 μ΄ˆμ μ„ λ§žμΆ”λ©°, νŠΉμ • 뷰의 생λͺ… μ£ΌκΈ° λ™μ•ˆ μƒνƒœ 객체가 μœ μ§€λ˜λ„λ‘ 보μž₯ν•œλ‹€.
### `@EnvironmentObject`

`@EnvironmentObject`λŠ” `ObservableObject` ν”„λ‘œν† μ½œμ„ λ”°λ₯΄λŠ” 객체λ₯Ό λ·° 계측 ꡬ쑰 μ „λ°˜μ— 걸쳐 κ³΅μœ ν•˜λŠ” 데 μ‚¬μš©λœλ‹€. SwiftUIμ—μ„œ ν™˜κ²½μ— μ˜ν•΄ μ£Όμž…λœ κ°μ²΄λŠ” `@EnvironmentObject`둜 μ°Έμ‘°ν•  수 있으며, 이λ₯Ό 톡해 μ•±μ˜ μ—¬λŸ¬ λΆ€λΆ„μ—μ„œ κ³΅ν†΅λœ μƒνƒœλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

* μ–Έμ œ μ‚¬μš©ν•΄μ•Ό ν• κΉŒ?
* μ•±μ˜ μ—¬λŸ¬ λΆ€λΆ„μ—μ„œ κ³΅ν†΅λœ μƒνƒœλ₯Ό κ³΅μœ ν•˜κ³  관리해야 ν•  λ•Œ μ‚¬μš©ν•œλ‹€.
* 예λ₯Ό λ“€μ–΄ μ‚¬μš©μž 인증 μƒνƒœ, μ „μ—­ μ„€μ •, 곡톡 데이터 μ†ŒμŠ€ 등을 `@EnvironmentObject`둜 관리할 수 μžˆλ‹€.
* 계측이 κΉŠμ€ λ·° κ΅¬μ‘°μ—μ„œ μƒμœ„λ·°μ—μ„œ ν•˜μœ„λ·°λ‘œ μƒνƒœλ₯Ό 계속 μ „λ‹¬ν•˜λŠ” λŒ€μ‹  `@EnvironmentObject`λ₯Ό μ‚¬μš©ν•΄ κ°„νŽΈν•˜κ²Œ μƒνƒœλ₯Ό 전달할 수 μžˆλ‹€.

`@EnvironmentObject`λŠ” λ·° κ³„μΈ΅μ˜ μƒμœ„μ—μ„œ μ£Όμž…λ˜μ–΄μ•Ό ν•œλ‹€. λ§Œμ•½ ν•΄λ‹Ή 객체가 μ£Όμž…λ˜μ§€ μ•Šμ€ ν•˜μœ„λ·°μ—μ„œ 이λ₯Ό μ‚¬μš©ν•˜λ €κ³  ν•˜λ©΄, λŸ°νƒ€μž„ μ—λŸ¬κ°€ λ°œμƒν•  수 μžˆλ‹€.
λ˜ν•œ 객체가 ν•„μš”ν•œ 뷰듀에 λͺ…μ‹œμ μœΌλ‘œ μ£Όμž…λ˜λ„λ‘ 신경써야 ν•˜λ©°, λͺ…μ‹œμ μœΌλ‘œ μ„ μ–Έλ˜μ§€ μ•Šμ€ `@EnvironmentObject`λŠ” λ·°μ—μ„œ μ˜λ„μΉ˜ μ•Šκ²Œ λ™μž‘ν•  수 μžˆλ‹€.

### `@Environment`

`@Environment`λŠ” μ‹œμŠ€ν…œμ—μ„œ μ œκ³΅ν•˜λŠ” λ‹€μ–‘ν•œ 값듀을 λ·°μ—μ„œ μ ‘κ·Όν•  수 있게 ν•΄μ£ΌλŠ” ν”„λ‘œνΌν‹° λž˜νΌλ‹€. 예λ₯Ό λ“€μ–΄ 색상 ν…Œλ§ˆ, μ‚¬μš©μžμ˜ μ ‘κ·Όμ„± μ„€μ •, λ ˆμ΄μ•„μ›ƒ λ°©ν–₯ 등을 `@Environment`λ₯Ό 톡해 κ°€μ Έμ˜¬ 수 μžˆλ‹€.

* μ–Έμ œ μ‚¬μš©ν•΄μ•Ό ν• κΉŒ?
* μ‚¬μš©μžμ˜ μ‹œμŠ€ν…œ 섀정에 따라 UI λ™μž‘μ΄λ‚˜ μŠ€νƒ€μΌμ„ λ³€κ²½ν•΄μ•Ό ν•  λ•Œ μ‚¬μš©λœλ‹€.
* 예λ₯Ό λ“€μ–΄ 닀크λͺ¨λ“œμ™€ 라이트 λͺ¨λ“œμ— 따라 색상을 μ‘°μ •ν•˜κ±°λ‚˜ μ ‘κ·Όμ„± 섀정에 따라 ν…μŠ€νŠΈ 크기λ₯Ό λ³€κ²½ν•΄μ•Ό ν•  λ•Œ μœ μš©ν•˜λ‹€.

`@Environment`λ₯Ό μ‚¬μš©ν•˜μ—¬ μ‹œμŠ€ν…œ ν™˜κ²½μ— μ˜μ‘΄ν•˜λŠ” UIλ₯Ό λ§Œλ“€ λ•ŒλŠ” ν•΄λ‹Ή 값이 항상 μ˜ˆμƒλŒ€λ‘œ μ œκ³΅λ˜λŠ”μ§€ 확인이 ν•„μš”ν•˜λ‹€. 예λ₯Ό λ“€μ–΄ νŠΉμ • ν™˜κ²½ 값은 ν…ŒμŠ€νŠΈλ‚˜ νŠΉμ • μƒν™©μ—μ„œ λ‹€λ₯΄κ²Œ 섀정될 수 μžˆλ‹€.

λ˜ν•œ λ„ˆλ¬΄ λ§Žμ€ `@Environment` 값을 μ‚¬μš©ν•˜λ©΄ μ½”λ“œκ°€ λ³΅μž‘ν•΄μ§€κ³  관리가 μ–΄λ €μ›Œμ§ˆ 수 μžˆμ–΄ κ³Όλ„ν•œ μ‚¬μš©μ€ ν”Όν•΄μ•Όν•œλ‹€.

```swift
@Environment(\.colorScheme) var colorScheme: ColorScheme

if colorScheme == .dark { // Checks the wrapped value.
DarkContent()
} else {
LightContent()
}
```

### `@AppStorage`

`@AppStorage`λŠ” iOS의 UserDefaultsλ₯Ό μ‚¬μš©ν•˜μ—¬ 값을 μ €μž₯ν•˜κ³ , 이 값을 μžλ™μœΌλ‘œ κ΄€λ¦¬ν•˜λŠ” ν”„λ‘œνΌν‹° λž˜νΌλ‹€. 이 λž˜νΌλŠ” κ°„λ‹¨ν•œ 값을 μ•± μ „μ—­μ—μ„œ μ§€μ†μ μœΌλ‘œ μœ μ§€ν•˜κ³ , 앱이 μž¬μ‹œμž‘λ˜λ”λΌλ„ κ·Έ 값을 μœ μ§€ν•  수 있게 ν•΄μ€€λ‹€.

* μ–Έμ œ μ‚¬μš©ν•΄μ•Ό ν• κΉŒ?
* μ‚¬μš©μžκ°€ μ„€μ •ν•œ κ°„λ‹¨ν•œ 값을 μ €μž₯ν•˜κ³ , 앱이 λ‹€μ‹œ μ‹œμž‘λ˜μ—ˆμ„ λ•Œλ„ ν•΄λ‹Ή 값을 μœ μ§€ν•˜κ³  싢을 λ•Œ μ‚¬μš©ν•œλ‹€.
* 예λ₯Ό λ“€μ–΄, μ‚¬μš©μž ν…Œλ§ˆ μ„€μ •, 둜그인 μƒνƒœ, λ˜λŠ” μ–Έμ–΄ 섀정을 `@AppStorage`λ₯Ό 톡해 관리할 수 μžˆλ‹€.

`@AppStorage`λŠ” UserDefaults에 데이터λ₯Ό μ €μž₯ν•˜λ―€λ‘œ, λ„ˆλ¬΄ λ§Žμ€ λ°μ΄ν„°λ‚˜ λ³΅μž‘ν•œ 객체λ₯Ό μ €μž₯ν•˜λŠ” 데 μ ν•©ν•˜μ§€ μ•Šλ‹€. 큰 λ°μ΄ν„°λ‚˜ λ³΅μž‘ν•œ ꡬ쑰λ₯Ό μ €μž₯ν•  경우 λ‹€λ₯Έ μ˜μ†μ„± λ©”μ»€λ‹ˆμ¦˜μ„ κ³ λ €ν•΄μ•Ό ν•œλ‹€.

λ˜ν•œ `@AppStorage`λŠ” κΈ°λ³Έ 데이터 νƒ€μž…λ§Œ μ§€μ›ν•œλ‹€. λ³΅μž‘ν•œ 데이터 κ΅¬μ‘°λ‚˜ μ‚¬μš©μž μ •μ˜ κ°μ²΄λŠ” Codable을 μ‚¬μš©ν•˜μ—¬ 직접 직렬화/역직렬화 ν•΄μ•Ό ν•œλ‹€.

### `@SceneStorage`

`@SceneStorage`λŠ” νŠΉμ • λ·°λ‚˜ μž₯λ©΄(Scene)의 μƒνƒœλ₯Ό μžλ™μœΌλ‘œ μ €μž₯ν•˜κ³  볡원할 수 μžˆλŠ” ν”„λ‘œνΌν‹° λž˜νΌλ‹€. μ΄λŠ” iOSμ—μ„œ 앱이 μ—¬λŸ¬ μž₯면을 κ°€μ§ˆ 수 있게 λ˜μ—ˆμ„ λ•Œ λ„μž…λœ κ°œλ…μœΌλ‘œ, 각 μž₯면에 κ΅­ν•œλœ μƒνƒœλ₯Ό μœ μ§€ν•˜λŠ” 데 μœ μš©ν•˜λ‹€.

* μ–Έμ œ μ‚¬μš©ν•΄μ•Ό ν• κΉŒ?
* μ‚¬μš©μžκ°€ νŠΉμ • ν™”λ©΄μ—μ„œ μž…λ ₯ν•˜λ˜ 데이터λ₯Ό μœ μ§€ν•˜κ±°λ‚˜, μž₯면이 λ‹€μ‹œ ν™œμ„±ν™”λ˜μ—ˆμ„ λ•Œ 이전 μƒνƒœλ₯Ό 볡원해야 ν•˜λŠ” κ²½μš°μ— μ‚¬μš©λœλ‹€.
* 예λ₯Ό λ“€μ–΄, μž…λ ₯ν•˜λ˜ ν…μŠ€νŠΈ ν•„λ“œμ˜ 값을 μ €μž₯ν•˜κ³ , μž₯면이 λ‹€μ‹œ ν™œμ„±ν™”λ˜μ—ˆμ„ λ•Œ 이λ₯Ό 볡원할 수 μžˆλ‹€.

`@SceneStorage`λŠ” μž₯λ©΄(Scene)이 μ†Œλ©Έλ˜λ©΄ ν•΄λ‹Ή μƒνƒœλ„ μ‚¬λΌμ§ˆ 수 μžˆλ‹€. μž₯기적인 μƒνƒœ μ €μž₯이 ν•„μš”ν•œ κ²½μš°μ—λŠ” λ‹€λ₯Έ ν”„λ‘œνΌν‹° 래퍼λ₯Ό κ³ λ €ν•΄μ•Ό ν•œλ‹€.
λ§Œμ•½ 앱이 예기치 μ•Šκ²Œ μ’…λ£Œλ˜κ±°λ‚˜, μž₯면이 μ™„μ „νžˆ 제거되면 `@SceneStorage`에 μ €μž₯된 데이터가 손싀될 수 μžˆλ‹€.

---


# 참고 링크


- [https://developer.apple.com/documentation/swiftui/state](https://developer.apple.com/documentation/swiftui/state)
- [https://developer.apple.com/documentation/swiftui/binding](https://developer.apple.com/documentation/swiftui/binding)
- [https://developer.apple.com/documentation/swiftui/observedobject](https://developer.apple.com/documentation/swiftui/observedobject)
- [https://developer.apple.com/documentation/combine/published](https://developer.apple.com/documentation/combine/published)
- [https://developer.apple.com/documentation/swiftui/stateobject](https://developer.apple.com/documentation/swiftui/stateobject)
- [https://developer.apple.com/documentation/swiftui/environmentobject](https://developer.apple.com/documentation/swiftui/environmentobject)
- [https://developer.apple.com/documentation/swiftui/environment](https://developer.apple.com/documentation/swiftui/environment)
- [https://developer.apple.com/documentation/swiftui/appstorage](https://developer.apple.com/documentation/swiftui/appstorage)
- [https://developer.apple.com/documentation/swiftui/scenestorage](https://developer.apple.com/documentation/swiftui/scenestorage)

0 comments on commit 57ac0d2

Please sign in to comment.