[英]CurrentValueSubject send(value) doesn't trigger receiveValue
我有一個CurrentValueSubject
來保存從Firebase
提取請求收到的數據。
final class CardRepository: ObservableObject {
private let store = Firestore.firestore()
var resultSubject = CurrentValueSubject<[Card], Error>([])
init() {
}
func get() {
store.collection(StorageCollection.EnglishCard.getPath)
.addSnapshotListener { [unowned self] snapshot, err in
if let err = err {
resultSubject.send(completion: .failure(err))
}
if let snapshot = snapshot {
let cards = snapshot.documents.compactMap {
try? $0.data(as: Card.self)
}
resultSubject.send(cards)
}
}
}
}
在我的 ViewModel 中,我希望每當resultSubject
發送或emits
一個value
時。 它將更改state
並將該value
附加到succes
state。
class CardViewModel: CardViewModelProtocol, ObservableObject {
@Published var repository: CardRepository
@Published private(set) var state: CardViewModelState = .loading
private var cancellables: Set<AnyCancellable> = []
required init (_ repository: CardRepository) {
self.repository = repository
bindingCards()
}
private func bindingCards() {
let _ = repository.resultSubject
.sink { [unowned self] comp in
switch comp {
case .failure(let err):
self.state = .failed(err: err)
case .finished:
print("finised")
}
} receiveValue: { [unowned self] res in
self.state = .success(cards: res)
}
}
func add(_ card: Card) {
repository.add(card)
}
func get() {
repository.get()
}
}
在我的 ContentView 上,它將顯示一個print
result
的按鈕。
struct ContentView: View {
@StateObject var viewModel = CardViewModel(CardRepository())
var body: some View {
Group {
switch viewModel.state {
case .loading:
ProgressView()
Text("Loading")
case .success(cards: let cards):
let data = cards
Button {
print(data)
} label: {
Text("Tap to show cards")
}
case .failed(err: let err):
Button {
print(err)
} label: {
Text("Retry")
}
}
Button {
viewModel.get()
} label: {
Text("Retry")
}
}.onAppear {viewModel.get() }
}
}
我的問題是當我第一次將它綁定到resultSubject
時,下面的塊只觸發一次。
} receiveValue: { [unowned self] res in
self.state = .success(cards: res)
}
我確實添加了調試,並且resultSubject.send(cards)
每次都有效。
您需要將從.sink
返回的Cancellable
存儲在 class 中,這樣它就不會被釋放:
如果您想使用多個Publishers
,或者在 var var cancellables = Set<AnyCancellable>()
中,或者在var cancellable: AnyCancellable?
.
像這樣添加.store(in &cancellables)
:
} receiveValue: { [unowned self] res in
self.state = .success(cards: res)
}.store(in: &cancellables)
編輯:
在ObservableObject
類中我們不使用sink
,我們assign
給一個@Published
:
let _ = repository.resultSubject
.assign(to: &$self.state)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.