首页 > 解决方案 > SwiftUI 应用程序的 API 调用

问题描述

我正在尝试在 SwiftUI for iOS 中制作一个简单的应用程序。我正在按照 YouTube 视频的说明进行操作,该视频展示了如何从 PokeAPI 进行 API 调用,以便在视图中显示口袋妖怪列表。我使每一步都等于视频中的每一步,但编译器在下面的代码中返回了类似这样的错误。

PokemonAPIList.swift

import Foundation

struct PokemonAPIList: Decodable {
    var results: [PokemonListEntry]
}

struct PokemonListEntry: Decodable {
    var name: String
    var url: String
}

PokemonNetworkManager.swift

import Foundation
import SwiftUI
import Combine

class PokemonNetworkManager: ObservableObject {
    var didChange = PassthroughSubject<PokemonNetworkManager, Never> ()
    
    var pokemonList = PokemonAPIList(results: []) {
        didSet {
            didChange.send(self)
        }
    }
    
    init() {
        guard let url = URL(string: "https://pokeapi.co/api/v2/pokemon?limit=151") else { return }
        
        URLSession.shared.dataTask(with: url) { (data, _, _) in
            guard let data = data else { return }
            
            let pokemonList = try! JSONDecoder().decode(PokemonAPIList.self, from: data)
            
            DispatchQueue.main.async {
                self.pokemonList = pokemonList
            }
        }.resume()
    }
}

内容视图.swift

import SwiftUI
    
struct ContentView: View {
    @State var networkingManager = PokemonNetworkManager()
    
    var body: some View {
        List(networkingManager.pokemonList.results.identified(by: \.url)) {pokemon in //HERE THE ERRORS
            Text(pokemon.name)
                .font(.largeTitle)
        }
    }
}

#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

出现以下错误:

无法从上下文推断关键路径类型;考虑明确指定根类型

插入“<#Root#>”

“[PokemonListEntry]”类型的值没有“已识别”成员

我唯一更改的是将@BindableObject 更改为@ObservableObject,因为我在线阅读它不再受支持。

标签: iosswiftapiswiftui

解决方案


你可以试试

import Foundation
import SwiftUI
import Combine
 
struct PokemonAPIList: Decodable {
    var results: [PokemonListEntry]
}

struct PokemonListEntry: Decodable {
    var name: String
    var url: String
}
 
class PokemonNetworkManager: ObservableObject {
  
   @Published var results = [PokemonListEntry]()
     
    init() {
        guard let url = URL(string: "https://pokeapi.co/api/v2/pokemon?limit=151") else { return }
        
        URLSession.shared.dataTask(with: url) { (data, _, _) in
            guard let data = data else { return }
            
            let pokemonList = try! JSONDecoder().decode(PokemonAPIList.self, from: data)
            
            DispatchQueue.main.async {
                self.results = pokemonList.results
            }
        }.resume()
    }
}
  
struct ContentView: View {
    @ObservedObject var networkingManager = PokemonNetworkManager()
    
    var body: some View {
        List(networkingManager.results,id:\.name) {pokemon in
            Text(pokemon.name)
                .font(.largeTitle)
        }
    }
}
 

在此处输入图像描述


推荐阅读