result with combine 得不到结果
Result with combine can't get results
我写的一切都是正确的,代码本身也能正常工作,但它给了我一个错误调用 'fetchPokemon()' 的结果未使用,这里可能是什么问题?
听到的是我的代码:ModelView class
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([=10=].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
函数 returns 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([=10=].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]
}
如果类型不同,您必须在 runFetch
中更改 receiveValue
中发生的情况。
我写的一切都是正确的,代码本身也能正常工作,但它给了我一个错误调用 'fetchPokemon()' 的结果未使用,这里可能是什么问题?
听到的是我的代码:ModelView class
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([=10=].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
函数 returns 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([=10=].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]
}
如果类型不同,您必须在 runFetch
中更改 receiveValue
中发生的情况。