Reputation: 871
I have LocationManager class that works well. This is part of LocationManager class.
var headingDegree = PassthroughSubject<Double, Never>()
func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
headingDegree.send(-newHeading.magneticHeading)
}
headingDegree
is the value I want to send to my ViewModel. I debugged it to make sure it has correct values, and it does.
So, in my view model,
class CompassViewViewModel: ObservableObject {
@Published var degree: Double = 0.0
@State var cancellable = Set<AnyCancellable>()
func update() {
LocationManager.shared.headingDegree.sink {
self.degree = $0
}
.store(in: &cancellable)
}
I sinked my headingDegree
. This is the part that brings my problems. If I put breakpoints in update()
function, self.degree = $0
is never called.
This is how my View looks like.
struct CompassView: View {
@ObservedObject var viewModel: CompassViewViewModel
init(viewModel: CompassViewViewModel) {
self.viewModel = viewModel
}
var body: some View {
ZStack {
Text("aa")
.font(.footnote)
}
.onAppear {
self.viewModel.update()
}
}
}
Could you tell me why my sink() is not called?
Upvotes: 4
Views: 3879
Reputation: 9266
Another manifestation of this is if you make the scope of the var cancellable = Set<AnyCancellable>()
function scope rather than instance scope. It frees it before the async code in the callbacks are called. Putting it in the instance keeps it alive long enough for calls to complete.
struct MyClass {
var cancellable = Set<AnyCancellable>() // here
func action() {
// var cancellable = Set<AnyCancellable>() // Not here
resourceLoader()
.sink { completion in
} receiveValue: { response in
print(response)
}
.store(in: &cancellable)
}
}
Upvotes: 0
Reputation: 927
in swiftUI1, viewDidLoad in UIHostingcontroller isn't called.
when using combine, with UIKit, subscribing (Sink) in viewDidload, didn't work, instead, subscribe in viewDidAppear
Upvotes: 1
Reputation: 871
I changed @State var cancellable = Set<AnyCancellable>()
to private var cancellable = Set<AnyCancellable>()
and it works well.
Upvotes: 3