首页 > 解决方案 > 结果与组合无法获得结果

问题描述

我有点正确地写了所有东西,代码本身正在工作,但它给了我一个错误调用“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()
    }
}

}

标签: swiftxcodeswiftuicombine

解决方案


您的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


推荐阅读