I'm playing with Combine to learn it and improve my reactive programming skills, and I'm trying to create some generic class that convert data to my T type
I have this error, and I don't understand why
Key path value type '[T]' cannot be converted to contextual type 'T'
class Fetcher<T: Codable>: ObservableObject {
private var task: AnyCancellable?
@Published var result = [T]()
init<T: Codable> (type: T.Type) {
guard let url = URL(string: "https://api.example.com") else { return }
task = URLSession.shared.dataTaskPublisher(for: url)
.map{$0.data}
.decode(type: T.self, decoder: JSONDecoder())
.receive(on: DispatchQueue.global(qos: .background))
.replaceError(with: T.self as! T)
.assign(to: \.result, on: self)
}
}
CodePudding user response:
Since the URL gives you an array of T
s, you should decode an array, rather than a single T
in the decode
call. This line
.decode(type: T.self, decoder: JSONDecoder())
should be:
.decode(type: [T].self, decoder: JSONDecoder())
That replaceError
call is going to crash your app, as T.self
is not a T
(it's a T.Type
), and you are force-casting. Since you are receiving an array, a logical choice for a value to replace errors with, is the empty array []
:
.replaceError(with: [])
Also, remove your generic parameter on init
:
init() {