728x90
Combine Framework
- 시간에 따라 값들을 처리하기 위한 선언적인 Swift API
- 시간에 따라 변할 수 있는 값으로 노출하기위해 publisher를 선언합니다
- publisher로부터 받아오기 위한 subscriber를 선언합니다.
- publisher는 시간에 따라 일련의 값을 전달할 수 있는 타입을 선언하며, 연산자를 사용하여 상위 발행자로부터 받은 값을 처리하고 다시 발행할 수 있습니다.
- subscriber는 publisher로부터 이벤트를 얼마나 빨리 받을지 제어 할 수 있습니다.
- 텍스트 필드의 업데이트와 URL 요청, 응 답 처리 등을 조율할 수 있습니다.
- 코드를 더 읽기 쉽고 유지 보수하기 쉽게 만들 수 있습니다.
- 이벤트 처리 코드를 중앙 집중화하여 중첩된 클로저 및 규약 기반 콜백과 같은 번거로운 기술을 제거할 수 있습니다.
data가 발행될때마다 receiveValue가 호출되고 데이터 스크림이 끝나게 되면 receiveCompletion이 호출
Publisher의 Subscriber 종류
Convenience Publisher
- 간단한 데이터 스트림을 생성하고 조작하는 데 사용.
- 예를 들어, 배열의 요소를 데이터 스트림으로 변환하거나 특정 시간 간격으로 이벤트를 생성하는데 유용
Just
- 오직 하나의 값만 출력하고 끝나게 되는 가장 단순한 형태
- Combine Freamework에서 (Built-in) 형태로 제공하는 Publisher
Promise
- Just와 비슷하지만 Filter Type을 정의 가능
Fail
- 정의된 실패타입을 내보냄
Empty
- 어떤 데이터도 발행하지 않는 퍼블리셔로 error, optional 값을 처리함
Sequence
- 데이터를 순차적으로 발행하는 Publisher로 (1…10).publisher처럼 쓰임
Framework 내장제공
- Foundation Farmework, Notification Center 처럼 프레임워크에서 직접적으로 제공하는 Provider는 개발자가 Subscribe만 구현하여 손쉽게 사용할 수 있음
- **ObservableObject**은 Combine 프레임워크의 기능을 활용하여 데이터의 변경을 처리하고 SwiftUI 뷰에 반영하는 역할을 함
Combine Code
예시 1 - 버튼을 눌러서 숫자 증가
import SwiftUI
import Combine
class CounterViewModel: ObservableObject {
@Published var count: Int = 0
private var cancellables = Set<AnyCancellable>()
init() {
// Combine을 사용하여 count의 변경을 구독하고 처리
$count
.sink { newValue in
print("Count changed to: \\(newValue)")
}
.store(in: &cancellables)
}
}
struct ContentView: View {
@ObservedObject var viewModel = CounterViewModel()
var body: some View {
VStack {
Text("Count: \\(viewModel.count)")
Button(action: {
self.viewModel.count += 1
}) {
Text("Increment")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
설명
- $count:
- Publisher로 생성된 count속성
- @Published 속성 래퍼로 감싸져 있어서 데이터의 변경이 발생하면 Combine 프레임워크에서 Publisher로 변환
- .sink:
- Combine에서 사용하는 구독(Subscription) 관련 연산자
- .store:
- Combine에서 Subscription을 수동으로 해제하거나 취소하지 않고 Subscription을 수행하는 동안 유지하고 싶을 때 사용
- Publisher 와 Subscriber간의 연결을 유지할때 사용
- Subscription을 자동으로 해제하기 위해 .store사용 만약 해제하지않으면 메모리 누수 발생
예시 2 - Text를 입력받아 대문자로 변환하여 표시
import SwiftUI
import Combine
class UserViewModel: ObservableObject {
@Published var userInput: String = ""
@Published private(set) var formattedInput: String = ""
private var cancellables = Set<AnyCancellable>()
init() {
// 사용자 입력이 변경될 때마다 대문자로 변환하여 formattedInput에 할당
$userInput
.map { $0.uppercased() }
.assign(to: \\.formattedInput, on: self)
.store(in: &cancellables)
}
}
struct ContentView: View {
@ObservedObject private var viewModel = UserViewModel()
var body: some View {
VStack {
TextField("Enter your name", text: $viewModel.userInput)
.padding()
.textFieldStyle(RoundedBorderTextFieldStyle())
Text("Hello, \\(viewModel.formattedInput)")
.padding()
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
설명
- .assign(to:on:)
- Combine 프레임워크에서 사용되는 연산자로, Publisher에서 생성된 값을 특정 속성에 할당할 때 사용
- 속성의 값이 변경될 때마다 값을 업데이트할 수 있도록 도우고 주로 뷰를 업데이트할때 사용
728x90
'SwiftUI > 정리' 카테고리의 다른 글
[SwiftUI] 아키텍처 고민 (0) | 2024.01.06 |
---|---|
[SwiftUI] Combine - 기본 (0) | 2023.09.16 |
[Swift] SwiftLint (0) | 2023.09.04 |
[SwiftUI] NavigationStack (0) | 2023.09.02 |
[Swift] 기본 문법 정리 (0) | 2023.03.19 |