要解码您的 json 数据,您必须首先获得与数据匹配的正确 swift 数据模型。
一种快速的方法是将您的 json 数据复制并粘贴到“https://quicktype.io/”中。
该站点将为您提供所需的快速结构。然后你需要进行请求调用
到服务器。鉴于 swift 数据结构,这是执行此操作的代码。
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@State var results = [Result]()
var body: some View {
List {
ForEach(results) { news in
VStack {
Text(news.title)
Text(news.link).foregroundColor(.blue)
}
}
}
.onAppear {
loadNews()
}
}
func loadNews() {
let jsonUrl = URL(string: "https://newsdata.io/api/1/news?apikey=YOURAPIKEY&q=travelling&language=en")
guard let url = jsonUrl else { return }
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else { return }
do {
let response = try JSONDecoder().decode(Response.self, from: data)
results = response.results
}
catch {
print("---> error: \(error)")
}
}
task.resume()
}
}
struct Response: Codable {
let status: String
let totalResults: Int
let results: [Result]
let nextPage: Int
}
struct Result: Identifiable, Codable {
let id = UUID()
let title: String
let link: String
let keywords: [String]?
let creator: [String]?
let videoURL: JSONNull?
let resultDescription, content: String?
let pubDate: String
let fullDescription: String?
let imageURL: String?
let sourceID: String
enum CodingKeys: String, CodingKey {
case title, link, keywords, creator
case videoURL = "video_url"
case resultDescription = "description"
case content, pubDate
case fullDescription = "full_description"
case imageURL = "image_url"
case sourceID = "source_id"
}
}
class JSONNull: Codable, Hashable {
public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
return true
}
public var hashValue: Int {
return 0
}
public init() {}
public required init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if !container.decodeNil() {
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encodeNil()
}
}
PS:请勿发布您的 API 密钥。立即将其从您的问题中删除。
EDIT-1:
如果出于某种原因确实需要,不要解码status 和totalResults 使属性let 并给它们一个初始值,如下所示。 Xcode 会告诉你这些不会被解码。
struct Response: Codable {
let results: [Result]
let status: String = "" // <-- here give the let a value
let totalResults: Int = 0 // <-- here give the let a value
let nextPage: Int = 0 // <-- here give the let a value
}
如果您不想使用这些字段,请删除它们:
struct Response: Codable {
let results: [Result]
}