First of all, you should better read this article carefully:
Processing URL Session Data Task Results with Combine
(You may have already read it, in such a case, read it again, carefully.)
With reading the article, I would write something like this:
APIClient
import UIKit
import Combine
class APIClient: NSObject {
func fetchData(urlStr: String) -> AnyPublisher<[MyModel], Never> {
guard let url = URL(string: urlStr) else {
let subject = CurrentValueSubject<[MyModel], Never>([])
return subject.eraseToAnyPublisher()
}
return URLSession.shared.dataTaskPublisher(for: url)
.map { $0.data }
.decode(type: [MyModel].self, decoder: JSONDecoder())
.replaceError(with: [])
.eraseToAnyPublisher()
}
}
ViewModel
import Foundation
import Combine
class ViewModel: NSObject {
@IBOutlet var apiClient: APIClient!
var cancellables = Set<AnyCancellable>()
func getGitData() -> AnyPublisher<[MyModel], Never> {
let urlStr = "https://api.github.com/repos/ReactiveX/RxSwift/events"
return apiClient.fetchData(urlStr: urlStr)
}
}
No need to use .sink, just return the modified publisher as AnyPublisher.
(You may want to use Future when you want to define another async method, but this does not seem to be the case.)
Or if you want to use viewModel.dataModels somewhere in the ViewController, I would change the ViewModel as follows:
import Foundation
import Combine
class ViewModel: NSObject {
@IBOutlet var apiClient: APIClient!
var cancellables = Set<AnyCancellable>()
private let dataModelSubject = CurrentValueSubject<[MyModel], Never>([])
var dataModels: [MyModel] {
get {dataModelSubject.value}
set {dataModelSubject.send(newValue)}
}
func getGitData() -> AnyPublisher<[MyModel], Never> {
let urlStr = "https://api.github.com/repos/ReactiveX/RxSwift/events"
apiClient.fetchData(urlStr: urlStr)
.sink { result in
print("view model: \(result.count)")
self.dataModels = result
}
.store(in: &cancellables)
return dataModelSubject.eraseToAnyPublisher()
}
}
This shows a little different behavior than the previous code, as CurrentValueSubject will send its initial data to subscribers. (0 seems to be the count of the initial value in your code.)
In your code, you hold instances of CurrentValueSubject only as a local constant and never call send to these instance. That does not seem to be the right usage of CurrentValueSubject.