swift - 结果与组合无法获得结果
问题描述
我有点正确地写了所有东西,代码本身正在工作,但它给了我一个错误调用“fetchPokemon()”的结果未使用,这里可能有什么问题?
听我的代码:ModelView 类
import Foundation
import Combine
class NetworkManager: ObservableObject {
let baseuRL = "https://pokeapi.co/api/v2/pokemon"
@Published var pokemon: [Pokemon] = []
var error: Error?
var cancellables: Set<AnyCancellable> = []
func fetchPokemon() -> Future<[Pokemon], Error> {
return Future<[Pokemon], Error> { promice in
guard let url = URL(string: "\(self.baseuRL)") else {
return promice(.failure(ApiError.unknowed))
}
URLSession.shared.dataTaskPublisher(for: url)
.tryMap { (data, response) -> Data in
guard let http = response as? HTTPURLResponse,
http.statusCode == 200 else {
throw ApiError.responseError
}
return data
}
.decode(type: PokemonList.self, decoder: JSONDecoder())
.receive(on: RunLoop.main)
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
break
case .failure(let error):
print(error)
}
}, receiveValue: {
promice(.success($0.results))
})
.store(in: &self.cancellables)
}
}
struct ContentView: View {
@StateObject var net = NetworkManager()
var body: some View {
List(net.pokemon, id: \.self) { pokemon in
Text(pokemon.name)
}.onAppear {
net.fetchPokemon()
}
}
}
解决方案
您的fetchPokemon
函数返回 a Future
,但您没有对它做任何事情 - 这就是您收到未使用错误的原因。
此外,在该函数中,您正在返回您的承诺,但没有对结果做任何事情。所以,你需要处理Future
这些结果并做一些事情。
它可能如下所示:
class NetworkManager: ObservableObject {
let baseuRL = "https://pokeapi.co/api/v2/pokemon"
@Published var pokemon: [Pokemon] = []
var error: Error?
var cancellables: Set<AnyCancellable> = []
//New function here:
func runFetch() {
fetchPokemon().sink { (completion) in
//handle completion, error
} receiveValue: { (pokemon) in
self.pokemon = pokemon //do something with the results from your promise
}.store(in: &cancellables)
}
private func fetchPokemon() -> Future<[Pokemon], Error> {
return Future<[Pokemon], Error> { promice in
guard let url = URL(string: "\(self.baseuRL)") else {
return promice(.failure(ApiError.unknowed))
}
URLSession.shared.dataTaskPublisher(for: url)
.tryMap { (data, response) -> Data in
guard let http = response as? HTTPURLResponse,
http.statusCode == 200 else {
throw ApiError.responseError
}
return data
}
.decode(type: PokemonList.self, decoder: JSONDecoder())
.receive(on: RunLoop.main)
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
break
case .failure(let error):
print(error)
}
}, receiveValue: {
promice(.success($0.results))
})
.store(in: &self.cancellables)
}
}
}
struct ContentView: View {
@StateObject var net = NetworkManager()
var body: some View {
List(net.pokemon, id: \.self) { pokemon in
Text(pokemon.name)
}.onAppear {
net.runFetch() //call runFetch instead of fetchPokemon
}
}
}
由于您没有包含代码,PokemonList
因此我对其内容进行了假设:
struct PokemonList: Codable {
var results: [Pokemon]
}
如果类型不同,则必须更改 in 中发生的receiveValue
情况runFetch
。
推荐阅读
- haskell - Haskell:创建函数实例
- javascript - 将函数导出到 app.js 时出现 NodeJS 错误
- python - Python - 'append' VS '+=' 效率
- javascript - 通过Javascript在复选框更改时隐藏或显示中继器内的跨度
- macos - 使用 mv 在 CLI 中移动目录但仅重命名文件
- php - SQLSTATE[42000]:语法错误或访问冲突:1235 这个版本的 MariaDB 还不支持“IN/ALL/ANY 左侧表达式中的 ROW 中的 SUBQUERY”
- python - 'if random.choice(x) = input(y)' 不执行下面的代码
- python-3.x - StringVar没有写入文件帮助python 3 tkinter
- c# - 如何使用 C# 运行 Lua 脚本?
- linux - 提交 -m 在暂存更改后不起作用