AsyncPublisher은 간단하고 비동기적으로 Publisher로부터 받는 데이터를 처리하고 싶을 때 사용합니다
코드로 이해하기
우선 AsyncPublisherDataManager라는 클래스가 있고 @Published로 선언된 [String] 타입의 데이터가 존재합니다.
addData 메서드를 이용하여 2초마다 데이터를 삽입하며 이것은 비동기적으로 수행됩니다.
class AsyncPublisherDataManager {
@Published var myData: [String] = []
func addData() async {
myData.append("Apple")
try? await Task.sleep(nanoseconds: 2_000_000_000)
myData.append("Banana")
try? await Task.sleep(nanoseconds: 2_000_000_000)
myData.append("Watermelon")
try? await Task.sleep(nanoseconds: 2_000_000_000)
myData.append("Orange")
}
}
Combine을 사용했을 때
다음으로는 AsyncPublisherViewModel로 위에 데이터를 Combine을 이용하여 데이터를 sink하여 뷰에 보여줄 데이터를 저장할 수 있습니다. init 함수가 실행된 이후 addSubscribers 메서드가 실행되어 데이터를 받아옵니다.
class AsyncPublisherViewModel: ObservableObject {
@MainActor @Published var dataArray: [String] = []
let manager = AsyncPublisherDataManager()
var cancellable = Set<AnyCancellable>()
init() {
addSubscribers()
}
private func addSubscribers() {
Task {
await MainActor.run {
manager.$myData
.receive(on: DispatchQueue.main)
.sink { dataArray in
self.dataArray = dataArray
}
.store(in: &cancellable)
}
}
}
func start() async {
await manager.addData()
}
}
AsyncPublisher를 사용했을 때
물론 위처럼 combine을 사용할 수 있습니다, 하지만 아래 AsyncPublisher를 사용했을 때 얼마나 간편해지는지 확인하면 앞으로도 AsyncPublisher를 사용할 것입니다.
class AsyncPublisherViewModel: ObservableObject {
@MainActor @Published var dataArray: [String] = []
let manager = AsyncPublisherDataManager()
init() {
addSubscribers()
}
private func addSubscribers() {
Task {
for await value in manager.$myData.values { // .value = AsyncPublisher
await MainActor.run {
self.dataArray = value
}
}
}
}
func start() async {
await manager.addData()
}
}
위에 데이터를 보여주기 위한 View
struct ContentView: View {
@StateObject private var viewModel = AsyncPublisherViewModel()
var body: some View {
ScrollView {
VStack {
ForEach(viewModel.dataArray, id: \.self) {
Text($0)
.font(.headline)
}
}
}
.task {
await viewModel.start()
}
}
}
'SwiftUI' 카테고리의 다른 글
AVFoundation 이용한 음성 녹음하기 (0) | 2024.05.30 |
---|---|
Sendable 프로토콜 (0) | 2024.05.25 |
MacPaw/OpenAI SwiftUI Package 분석하기 (0) | 2024.05.25 |
Global Actor과 Main Actor (0) | 2024.05.24 |
Actor (0) | 2024.05.21 |