티스토리 뷰
[SwiftUI] @Observable, @ObservationTracked, @ObservationIgnored 알아보기
말차프라푸치노 2023. 10. 16. 23:01WWDC23에서 SwiftUI에 Observation 프레임워크가 새로 추가되었습니다. 이번 글에서는 @Observable 매크로 사용법과 추가적인@ObservationTracked, @ObservationIgnored 매크로의 사용법을 알아보겠습니다.
Discover Observation in SwiftUI - WWDC23 - Videos - Apple Developer
Simplify your SwiftUI data models with Observation. We'll share how the Observable macro can help you simplify models and improve your...
developer.apple.com
공식문서 훑어보기
공식문서의 정의를 직역하면 "기본 데이터가 변경될 때 화면을 업데이트하는 응답형 앱을 만듭니다." 입니다. 더 쉽게 풀어쓰면 "데이터 변경시 화면 업데이트"로 이해할 수 있습니다.
사실 데이터가 변화함에 따라 View 업데이트를 해주는 건 기존에도 있었습니다. ObservableObject, @Published, @ObservedObject를 사용해 model이 바뀌면 View를 자동으로 변경해주었습니다.
간단한 코드를 통해 확인해보겠습니다.
import SwiftUI
class ObservationViewModel: ObservableObject {
@Published var count: Int = 0
func countUp() {
count += 1
}
}
struct ObservationView: View {
@ObservedObject var viewModel = ObservationViewModel()
var body: some View {
Text("\(viewModel.count)")
Button(
action: { viewModel.countUp() },
label: { Text("카운트 업") }
)
.buttonStyle(.borderedProminent)
}
}
SwiftUI를 사용했으면 많이 봤을 코드입니다. 버튼을 클릭하면 ViewModel에 있는 count가 증가하고, ViewModel을 @ObservedObject로 명시해주었기 때문에 View가 업데이트 됩니다.
간단한 코드의 경우는 괜찮지만 실제 프로젝트를 진행하다 보면 count 하나가 아니라 ViewModel에 더 많은 프로퍼티가 있을 겁니다.
class ObservationViewModel: ObservableObject {
@Published var count: Int = 0
@Published var modelList1: [Model] = []
@Published var modelList2: [Model] = []
@Published var modalPresented: Bool = false
@Published var alertPresented: Bool = false
// ...
}
프로퍼티가 증가할 때마다 @Published를 작성하는 건 비효율적이고 귀찮습니다. @Observable를 사용하면 이를 더 쉽게 해결할 수 있습니다.
@Observable 사용하기
@Observable를 사용하기 위해서는 Observation을 import해줘야 합니다. Observation이 SwiftData내부에 있어 SwiftData를 import해줘도 됩니다. (더 명시적인 걸 위해 import Observation를 추천하고 있습니다)
import Observation
// import SwiftData
위에서 작성했던 코드를 아래처럼 작성할 수 있습니다.
@Observable
class ObservationViewModel {
var count: Int = 0
func countUp() {
count += 1
}
}
struct ObservationView: View {
var viewModel = ObservationViewModel()
// ...
}
훨씬 깔끔해지지 않았나요?? @Published와 @ObservedObject 프로퍼티 래퍼가 없으니까 가독성이 더 증가했습니다! 프로퍼티가 늘어나고 반복되는 @Published를 작성할 필요도 없습니다.
@ObservationIgnored
ViewModel에 있는 모든 프로퍼티를 View에서 보여주지 않는 경우가 있습니다. 기존에는 @Published 래퍼를 안 사용하면 됐지만 @Observable 매크로를 사용할 때는 @ObservationIgnored 래퍼를 사용해주면 됩니다.
@Observable
class ObservationViewModel {
@ObservationIgnored var count: Int = 0
func countUp() {
count += 1
print(count)
}
}
@ObservationIgnored를 사용해 count를 정의했습니다.
count가 Up 되서 출력되는데 View는 업데이트 되지않는 걸 볼 수 있습니다!
@ObservationTracked
Observation에 @ObservationIgnored와 더불어 @ObservationTracked 메크로가 있습니다.
공식문서에 있는데 따로 정의나 사용법은 나와있지가 않습니다. 그래서 일단 써봤습니다.
@Observable
class ObservationViewModel {
@ObservationTracked var count: Int = 0
func countUp() {
count += 1
}
}
위와 같이 코드를 수정했더니 에러가 발생했습니다.
_count를 찾을 수 없다고 하네요. _ 를 보니 프로퍼티 래퍼가 생각났습니다.
struct SmallRectangle {
private var _height = TwelveOrLess()
private var _width = TwelveOrLess()
var height: Int {
get { return _height.wrappedValue }
set { _height.wrappedValue = newValue }
}
var width: Int {
get { return _width.wrappedValue }
set { _width.wrappedValue = newValue }
}
}
Swift 공식문서 코드입니다. private 키워드를 사용해 _height와 _width를 외부로부터 숨기고 height, width를 통해서만 접근합니다.
매크로를 확대해보면 구현을 확인할 수 있습니다.
역시 접근을 숨겨주도록 구현했네요. View에서는 말 그대로 보여주기만 하고, 프로퍼티를 set하는 로직은 viewModel에서만 함으로 코드를 캡슐화 해주었습니다. @ObservationTracked를 사용해서 다시 코드를 작성했습니다.
@Observable
class ObservationViewModel {
@ObservationTracked var count: Int
@ObservationIgnored private var _count: Int = 0
func countUp() {
count += 1
print(_count)
}
}
struct ObservationView: View {
var viewModel = ObservationViewModel()
var body: some View {
Text("\(viewModel.count)")
//...
}
}
private으로 선언해 _count를 숨기고 view에서는 count로만 접근합니다. count를 증가시켜도 set으로 인해 _count가 증가합니다.
@Observable를 통해 반복되는 코드를 줄일 수 있어 매우 편하네요!
이상 @Observable 끝~~~~~~~~~~~~끝
참고
Observation | Apple Developer Documentation
Make responsive apps that update the presentation when underlying data changes.
developer.apple.com
'SwiftUI > SwiftUI 공부' 카테고리의 다른 글
[SwiftUI] WKWebView 사용하기 (with 양방향 이벤트 전달) (1) | 2023.10.12 |
---|---|
SwiftUI Animation 안될 때 (feat. 생명주기) (0) | 2023.10.06 |
[SwiftUI] Color 사용하는 7가지 방법 (0) | 2022.09.12 |
- Total
- Today
- Yesterday
- 부스트캠프7기
- Swift 서버
- 책
- Swift DocC
- UX
- swiftUI 기초
- 프로그래머스
- 필독서
- ios
- 책리뷰
- Swift공식문서
- vapor
- 애플
- 개발
- 부스트캠프iOS
- Swift문법
- 코딩
- Swift 디자인 패턴
- 부스트캠프
- 코딩테스트
- TODO
- SwiftUI
- 책후기
- 앱개발
- 날씨어플
- Combine
- Swift
- 코딩 테스트
- todo앱
- 디자인 패턴
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |