I have created a gravityPublisher
(to receive updates in the current gravity vector) and subscribe to it by calling the following function:
private func enableGravityDetection(_ gravityEnabled: Bool) {
if gravityEnabled {
if cancellable == nil {
cancellable = gravityProvider
.gravityPublisher
.receive(on: RunLoop.main)
.print()
.assign(to: \.gravity, on: self)
}
} else {
cancellable?.cancel()
}
}
The gravityPublisher
itself is just a CurrentValueSubject
private var gravitySubject =
CurrentValueSubject<CMAcceleration, Never>(CMAcceleration())
erased to AnyPublisher<CMAcceleration, Never>
. The cancellable
is stored as a state property as follows:
@State private var cancellable: Cancellable?
I need to call this function from within a SwiftUI view. When I call it from an onAppear
block everything works as expected and I continuously receive gravity vector updates:
struct CustomView: View {
var body: some View {
MyView()
.onAppear {
enableGravityDetection(true)
}
}
}
However, when I call the same (unmodified) function from the view's initializer, I don't receive any gravity updates as the subscription is immediately canceled:
struct CustomView: View {
init() {
enableGravityDetection(true)
}
var body: some View {
MyView()
}
}
The print()
statement in the stream above prints the following output in this case:
receive subscription: (ReceiveOn)
request unlimited
receive cancel // ← Why?
Why is that and how can I fix this?
I need to call this function in the initializer as I sometimes need to stop receiving gravity updates and need to decide this every time the view is recreated. (onAppear
is only called once.)