I have a problem of using combine send and sink method.
the publisher like this
//ViewModel
let reviewCellData = CurrentValueSubject<[ArchivingReviewCellModel], Never>([])
I surely checked the promise(.success) called.
//ViewModel
func fetchArchivingData(page: Int) -> Future<Archiving, Never> {
return Future<Archiving, Never> { promise in
//
let task = URLSession.shared.dataTask(with: request) { data, response, error in
//
do {
let decodedData = try JSONDecoder().decode(ArchiveResponseDTO.self, from: data!)
let archiving = decodedData.toDomain()
print("Promise success")
promise(.success(archiving))
} catch let decodingError {
//
}
}
task.resume()
}
}
and right after, the reviewCellData send the data.
//ViewModel
func fetchReviewCellData(page: Int) {
fetchArchivingData(page: page).subscribe(on: utilityQueue)
.sink(receiveValue: { [weak self] receivedValue in
guard let self = self else { return }
if page == 1 {
let sendValue = convertToReviewCellModels(from: receivedValue)
print("send Now!")
self.reviewCellData.send(sendValue)
} else {
let oldValue = self.reviewCellData.value
let newValue = oldValue + convertToReviewCellModels(from: receivedValue)
self.reviewCellData.send(newValue)
}
}).store(in: &bag)
}
I already set the subscriber using sink
//View
private func setupDataSubscription() {
print("Setting subscriber")
viewModel.reviewCellData.sink { [weak self] cellModels in
print("Receive Now! : \(cellModels)")
self?.updateUI(with: cellModels)
}.store(in: &bag)
}
But after the publisher send data(sendValue), the sink not called. It`s also sure that view has viewModel and already initialized.
None of your sample code shows fetchReviewCellData
being called. Without that call none of your pipelines are going to fire. I converted your code to a playground and added a call to fetchReviewCellData
and it seems to work without trouble. If there is a problem with your code then it is in areas that you are not showing.
Here is the playground code I wrote. If you are still not able to solve your issue then you might try boiling it down to a Minimal, Reproducible, example and see if that gives you an insight.
import UIKit
import Combine
var greeting = "Hello, playground"
typealias ArchivingReviewCellModel = Int
var bag = Set<AnyCancellable>()
enum Archiving {
case yupArchiving
}
let reviewCellData = CurrentValueSubject<[ArchivingReviewCellModel], Never>([])
func fetchArchivingData(page: Int) -> Future<Archiving, Never> {
return Future<Archiving, Never> { promise in
Task {
try await Task.sleep(nanoseconds: 1 * NSEC_PER_SEC)
print("Promise success")
promise(.success(.yupArchiving))
}
}
}
func convertToReviewCellModels(from: Archiving) -> [ArchivingReviewCellModel] {
return []
}
let utilityQueue = DispatchQueue.global(qos: .utility)
func fetchReviewCellData(page: Int) {
fetchArchivingData(page: page).subscribe(on: utilityQueue)
.sink(receiveValue: { receivedValue in
if page == 1 {
let sendValue = convertToReviewCellModels(from: receivedValue)
print("send Now!")
reviewCellData.send(sendValue)
} else {
let oldValue = reviewCellData.value
let newValue = oldValue + convertToReviewCellModels(from: receivedValue)
reviewCellData.send(newValue)
}
}).store(in: &bag)
}
private func setupDataSubscription() {
print("Setting subscriber")
reviewCellData.sink { cellModels in
print("Receive Now! : \(cellModels)")
}.store(in: &bag)
}
setupDataSubscription()
fetchReviewCellData(page: 3)
output:
Setting subscriber
Receive Now! : []
Promise success
Receive Now! : []