0

我在尝试获取此数据时遇到问题。听说有诀窍。任何人都可以创建一个简单的调用来查看来自这个 api 的数据吗?真的很感激。尝试了一周。我一辈子都无法让这个简单的 api 调用正常工作。

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

模型.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
}

内容视图.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)
    }
    
    
}
4

1 回答 1

0

将整个 json 从:“https://api.citybik.es/v2/networks”复制到“https://app.quicktype.io/”并从中获取(正确的)快速数据结构。将“欢迎”重命名为“响应”并在您的代码中使用它。

使用:“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 for 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
        }
    }
}
于 2021-07-15T04:28:52.430 回答