I have an enum in my project:
enum Remote<Content> {
case .notAsked
case .loading
case .loaded(Content)
case .failed(Error)
}
I then have a class:
class MyViewModel: ObservableObject {
@Published var content: Remote<ContentStruct> = .notAsked
func fetchContent() {
content = .loading
service.fetchContent()
.receive(on: queue)
.map(Remote<ContentStruct>.loaded)
.catch { error in Just(.failed(error)) }
.assign(to: &self.content)
}
}
But this complains to me that:
Cannot convert value of type 'Remote<ContentStruct>' to expected argument type 'Published<Remote<ContentStruct>>.Publisher'
I can change it to use this:
func fetchContent() {
content = .loading
service.fetchContent()
.receive(on: queue)
.map(Remote<ContentStruct>.loaded)
.catch { error in Just(.failed(error)) }
.assign(to: \.content, on: self)
.store(in: &cancellables)
}
And this works and assigns the value correctly. But I don't understand why I can't use the .assign(to: keyPath)
function on there?
Do I need to do something different? We've only recently updated to support a minimum of iOS14 and so not been using assign(to:
before due to memory leaks and now I'm just not sure how this is working.
Thanks
CodePudding user response:
assign(to:)
requires a Published.Publisher
as its input. So you need to pass the publisher from the Publisher
property wrapper, which you can access using the $
prefix.
.assign(to: &$content)