【问题标题】:Result with combine can't get results结果与组合无法获得结果
【发布时间】:2021-04-04 06:02:37
【问题描述】:

我写的一切都是正确的,代码本身正在运行,但它给了我一个错误调用“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()
    }
}

}

【问题讨论】:

    标签: swift xcode swiftui combine


    【解决方案1】:

    您的 fetchPokemon 函数返回一个 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]
    }
    

    如果类型不同,您必须将receiveValue 中发生的内容更改为runFetch。

    【讨论】:

    • 谢谢,一切正常,但我有点不明白为什么不可能在一个函数中做到这一点,事实证明你需要在一个函数中创建一个会话并在秒
    • 您可以一次性完成所有操作。您可以将接收器和存储连接到您最初拥有的末尾,而不是返回 Future。不过,它看起来有点乱。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 2015-01-10
    • 2018-07-09
    • 2021-07-21
    • 2019-03-24
    • 1970-01-01
    相关资源
    最近更新 更多