【问题标题】:Calling a web API via Swift通过 Swift 调用 Web API
【发布时间】:2022-01-23 22:32:26
【问题描述】:

我遇到了这个问题,我不确定我做错了什么,什么都没有显示。我很肯定我这样做是正确的(我想我不是),但我无法弄清楚我做错了什么。我是 Swift 的新手,所以我还在学习,这就是为什么我从这种方法中采用它,因为我想以最简单的方式做到这一点。所以我的问题是,我做错了什么?

SwiftUI 代码:

//
//  ContentView.swift
//  APIExample

import SwiftUI
struct Response: Codable {
    var articles: [Article]
}

struct Article: Codable, Identifiable {
    var id = UUID()
    var author: String
    var title: String
}

struct ContentView: View {
    @State private var articles = [Article]()
    func loadData() async {
        guard let url = URL(string: "https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=APIKEY") else {
            print("Invalid URL")
            return
        }
        do {
            let (data, _) = try await URLSession.shared.data(from: url)

            if let decodedResponse = try? JSONDecoder().decode(Response.self, from: data) {
                articles = decodedResponse.articles
            }
        } catch {
            print("Invalid data")
        }
    }
    var body: some View {
        List(articles, id: \.id) { item in
            VStack(alignment: .leading) {
                Text(item.author)
                    .font(.headline)
                Text(item.title)
            }
        }.task {
            await loadData()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

JSON:https://pastebin.com/Zn4kY2BV

【问题讨论】:

  • 首先,您忽略了错误。而不是try? JSONDecoder()... 使用try JSONDecoder()... 并打印错误:print("Invalid data: \(error)")

标签: swift swiftui


【解决方案1】:

你得到的错误是:

Invalid data: keyNotFound(CodingKeys(stringValue: "id", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "articles", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"id\", intValue: nil) (\"id\").", underlyingError: nil))

您可以通过提供自定义解码初始化来修复错误

struct Article: Codable, Identifiable {
    var id = UUID()
    var author: String
    var title: String
  
  enum CodingKeys: CodingKey {
    case author
    case title
  }
  
  init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    author = try container.decode(String.self, forKey: .author)
    title = try container.decode(String.self, forKey: .title)
  }
}

【讨论】:

  • 非常感谢您的成功。现在是我去研究它到底在做什么的时候了哈哈。再次感谢
【解决方案2】:

idJSON 中,但不是您在代码中指定的方式:

struct Response: Codable {
    var articles: [Article]
}
struct Source: Codable {
    var id: String
    var name: String
}
struct Article: Codable, Identifiable {
    var source = Source
    var author: String
    var title: String

}

为了你的ListView()

List(articles) { item in
        VStack(alignment: .leading) {
            Text(item.author)
                .font(.headline)
            Text(item.title)
        }
}

【讨论】:

    【解决方案3】:

    只需使用它,你就可以开始了:

    struct Article: Codable, Identifiable {
        let id = UUID()  // <-- here use let 
        var author: String
        var title: String
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-14
      • 1970-01-01
      • 2018-11-27
      • 1970-01-01
      • 2021-08-04
      • 2014-01-18
      • 1970-01-01
      相关资源
      最近更新 更多