iOS 13, Swift 5.x
I am trying to get the syntax right on a combine subscription/publisher. I got a working example and I have tried to copy it, but I missing something; and I cannot see the wood for the trees. Here is my code.
import Foundation
import Combine
class SwiftUIViewCModel: ObservableObject {
@Published var state : SwiftUIViewCModelState = .page1
static let shared = SwiftUIViewCModel()
private var stateUpdatingSubscriber: AnyCancellable?
init() {
self.stateUpdatingSubscriber = nil
self.stateUpdatingSubscriber = SwiftUIViewCModel.shared.$state
.map(modelCTomodelD(modelState:))
.receive(on: RunLoop.main)
.assign(to: \.state, on: self)
}
private func modelCTomodelD(modelState: SwiftUIViewCModelState) -> SwiftUIViewEModelState {
switch modelState {
case .page1:
return .page1
case .page2:
return .page2
default:
break
}
}
}
enum SwiftUIViewEModelState {
case page1
case page2
}
enum SwiftUIViewCModelState {
case page1
case page2
}
I am getting a syntax error on the compile, but I don't understand what exactly I need to do to fix it.
Cannot convert value of type '(SwiftUIViewCModelState) -> SwiftUIViewEModelState' to expected argument type 'KeyPath<Published.Publisher.Output, SwiftUIViewCModelState>' (aka 'KeyPath<SwiftUIViewCModelState, SwiftUIViewCModelState>')
How do I get the format it needs here into this code?
Thanks
I'm not really sure what the purpose of this code is.
The error you're getting is that self.state
is of type SwiftUIViewCModelState
, but the value was converted to a SwiftUIViewEModelState
via the map
operator. The last step (.assign(to: \.state, on: self)
) tries to save this new value back to the original self.state
var, but it can't, because it's now a different type.
I'm also not sure why you'd want to have a publisher/subscriber chain to modify a variable and save it back to itself?
One way to make the code compile is to add a new variable, var state2: SwiftUIViewEModelState
, and then change the .assign
line to .assign(to: \.state2, on: self)
. This will create a subscription chain that uses the state
var as the publisher, changes its type via map
, and then saves the modified value to state2
.