SwiftUI 正在从 api.city.bik JSON API 中获取数据

SwiftUI Fetching JSON API Data from api.city.bik

我在尝试获取此数据时遇到问题。听说有个窍门。任何人都可以创建一个简单的调用来查看来自 api 的数据吗?真的很感激。试了一个星期了。我这辈子都打不通这个简单的 api 上班电话。

http://api.citybik.es/v2/networks

Model.swift

import Foundation

// MARK: - Welcome
struct Dataset: Codable {
    let networks: [Network]
}

// MARK: - Network
struct Network: Codable {
    let company: [String]
    let href, id: String
    let location: Location
    let name: String
}

// MARK: - Location
struct Location: Codable {
    let city, country: String
    let latitude, longitude: Double
}

Contentview.swift

import SwiftUI

struct ContentView: View {
    
    @State var results = [Network]()
    
    func loadData() {
        guard let url = URL(string: "http://api.citybik.es/v2/networks") else {
            print("Your API end point is Invalid")
            return
        }
        let request = URLRequest(url: url)

        URLSession.shared.dataTask(with: request) { data, response, error in
            if let data = data {
                if let response = try? JSONDecoder().decode([Network].self, from: data) {
                    DispatchQueue.main.async {
                        self.results = response
                    }
                    return
                }
            }
        }.resume()
    }
    
    var body: some View {
        List(results, id: \.name) { item in
            VStack(alignment: .leading) {
                Text("\(item.name)")
            }
        }.onAppear(perform: loadData)
    }
    
    
}

从 https://api.citybik.es/v2/networks 复制整个 json 进入“https://app.quicktype.io/”并从中获取(正确的)swift 数据结构。 将“Welcome”重命名为“Response”并在您的代码中使用它。

使用:“https://api.citybik.es/v2/networks”注意 https.

编辑:在您的代码中:

struct ContentView: View {
    @State var networks = [Network]()
    
    var body: some View {
        List(networks, id: \.id) { network in
            VStack {
                Text(network.name)
                Text(network.location.city)
            }
        }.onAppear(perform: loadData)
    }
    
    func loadData() {
        guard let url = URL(string: "https://api.citybik.es/v2/networks") else {
            print("Your API end point is Invalid")
            return
        }
        let request = URLRequest(url: url)
        URLSession.shared.dataTask(with: request) { data, response, error in
            if let data = data {
                if let response = try? JSONDecoder().decode(Response.self, from: data) {
                    DispatchQueue.main.async {
                        self.networks = response.networks
                    }
                    return
                }
            }
        }.resume()
    }
} 

一旦你拥有了所有的数据结构, 如果您将 Swift 5.5 用于 ios 15 或 macos 12,则可以使用如下内容:

struct ContentView: View {
    @State var networks = [Network]()
    
    var body: some View {
        List(networks, id: \.id) { network in
            VStack {
                Text(network.name)
                Text(network.location.city)
            }
        }
        .task {
            let response: Response? = await fetchNetworks()
            if let resp = response {
                networks = resp.networks
            }
        }
    }
    
    func fetchNetworks<T: Decodable>() async -> T? {
        let url = URL(string: "https://api.citybik.es/v2/networks")!
        let request = URLRequest(url: url)
        do {
            let (data, response) = try await URLSession.shared.data(for: request)
            guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
                // throw URLError(.badServerResponse)   //  todo
                print(URLError(.badServerResponse))
                return nil
            }
            let results = try JSONDecoder().decode(T.self, from: data)
            return results
        }
        catch {
            return nil
        }
    }
}