async-await“表达式类型不明确,没有更多上下文”错误 - 在 swiftUI 中

Tol*_*ğan 7 swift swiftui

在这一行中DispatchQueue.main.async我收到此错误:

没有更多上下文,表达类型不明确

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 ?? []
    }
}
Run Code Online (Sandbox Code Playgroud)

jn_*_*pdx 5

该错误(诚然,这里是非描述性且无用的)是因为您试图将[ProductViewModel](这就是您的map返回值)设置为productList类型[Product]

ProductViewModel这里似乎没有任何目的——它只是产品的一个相同的包装。您可以将块内的代码更改do为:

let products = try await webService.getData(url: url)
DispatchQueue.main.async {
    self.productList = products
}
Run Code Online (Sandbox Code Playgroud)

为了进一步重构,您应该用ProductListViewModelwith进行注释@MainActor,以确保在主队列上设置其属性,然后您可以摆脱调用DispatchQueue.main.async——新的async/awaitAPI 不能很好地混合DispatchQueue,反之亦然。

@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")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)