My subscriber cannot receive subscription

49 views Asked by At

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.

enter image description here

1

There are 1 answers

0
Scott Thompson On BEST ANSWER

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! : []