In this line DispatchQueue.main.async
I get this error:
Type of expression is ambiguous without more context
import Foundation
class ProductListViewModel: ObservableObject {
@Published var productList = [Product]()
let webService = WebService()
func downloadData(url: URL) async {
do {
let product = try await webService.getData(url: url)
DispatchQueue.main.async {
self.productList = product.map(ProductViewModel.init)
}
} catch {
print("error")
}
}
}
struct ProductViewModel {
let productModel: Product
var id: Int {
productModel.id
}
var title: String {
productModel.title
}
var price: Double {
productModel.price
}
var description: String {
productModel.description
}
var category: Category {
productModel.category
}
var imageUrl: String {
productModel.imageUrl
}
var rating: Rating {
productModel.rating
}
}
struct WebService {
func getData(url: URL) async throws -> [Product] {
let (data, _) = try await URLSession.shared.data(from: url)
let product = try? JSONDecoder().decode([Product].self, from: data)
return product ?? []
}
}
CodePudding user response:
The error (which is admittedly nondescriptive and unhelpful here) is because you're trying to set [ProductViewModel]
(which is what your map
returns) to productList
which is of the type [Product]
.
ProductViewModel
doesn't seem to have a purpose here -- it's just an identical wrapper around product. You can change your code inside the do
block to this:
let products = try await webService.getData(url: url)
DispatchQueue.main.async {
self.productList = products
}
To further refactor, you should annotate your ProductListViewModel
with @MainActor
to ensure its properties get set on the main queue and then you can get rid of the DispatchQueue.main.async
call -- the new async/await
API doesn't mix well with DispatchQueue
and vice versa.
@MainActor class ProductListViewModel: ObservableObject {
@Published var productList = [Product]()
let webService = WebService()
func downloadData(url: URL) async {
do {
let products = try await webService.getData(url: url)
self.productList = products
} catch {
print("error")
}
}
}