Swift - Combine - combineLatest
What is it?
CombineLatest is an operator that combines more than one publishers, then provides a tuple of the latest value from each publisher.
The combined publisher doesn’t produce elements until each of its upstream publishers publishes at least one element.
When to use?
When we want the downstream subscriber to receive the data of the most-recent element from more than one publishers.( when any of them emit a value.)
BMI Calculator example:
class BMIViewmOdel: ObservableObject {
@Published var height: Double = 0
@Published var weight: Double = 0
@Published var bmi: Double = 0
@Published var type: String = "Obese"
private var cancellables = Set<AnyCancellable>()
init() {
Publishers.CombineLatest($height, $weight)
.map { height, weight in
let heightInMeters = height / 100
return weight/(heightInMeters * heightInMeters)
}
.sink{ [weak self] (bmi: Double) in
self?.bmi = bmi
self?.updateType(bmi)
}.store(in: &cancellables)
}
private func updateType(_ bmi: Double) {
self.type = switch bmi {
case ..<18.5: "Underweight"
case 18.5..<24.9: "Normal"
case 24.9..<29.9: "Overweight"
default: "Obeese"
}
}
}
struct ContentView: View {
@StateObject var viewModel : BMIViewmOdel = BMIViewmOdel()
var body: some View {
Form {
Section("Input") {
TextField("Height", value: $viewModel.height, format: .number, prompt: Text("Enter heigh"))
TextField("Weight", value: $viewModel.weight, format: .number, prompt: Text("Enter the weight"))
}
Section("Result") {
Text("BMI: \(viewModel.bmi)")
Text("Category: \(viewModel.type)")
}
} .navigationTitle("BMI Calculator")
}
}
Key items to note:
1. Won't emit ANY values until ALL publishers have emitted at least once
2.After the initial values are received, CombineLatest maintains the most recent value from each publisher. (Even if it is a passthrough subject although passthrough subject does not hold the value. :) )
Subscribe to my newsletter
Read articles from Radhakrishnan Selvaraj directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by