【问题标题】:SwiftUI Fetching JSON API Data from api.city.bikSwiftUI 从 api.city.bik 获取 JSON API 数据
【发布时间】:2021-07-15 03:13:14
【问题描述】:

我在尝试获取此数据时遇到问题。听说有诀窍。任何人都可以创建一个简单的调用来查看来自这个 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
}

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)
    }
    
    
}

【问题讨论】:

  • “我有问题”是什么?

标签: json api swiftui urlsession fetchrequest


【解决方案1】:

从以下位置复制整个 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()
    }
} 

一旦你有了所有的数据结构, 如果你在 ios 15 或 macos 12 上使用 Swift 5.5,你可以使用这样的东西:

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
        }
    }
}

【讨论】:

  • 感谢您的回复。我被困在使用 Xcode 12.5 进行这个测试,所以我无法使用新的 Swift 5.5。你不会偶然知道我该怎么做吧?如果你没有时间,我明白。我非常感谢您的回复。谢谢
  • 我下载了 xcode 13 并使用 swift 5.5,这确实有效。忘了提那个。非常感谢
  • 很高兴它成功了。我已经更新了我的答案,您可能需要针对 xcode 12.5 进行调整。
  • 你太棒了。 tysm :)
猜你喜欢
  • 2021-07-09
  • 2012-01-29
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
相关资源
最近更新 更多