gpt4 book ai didi

json - 解码 JSON 对象(发送带参数的 GET 请求) - Swift 4 Decodable

转载 作者:搜寻专家 更新时间:2023-11-01 07:08:01 25 4
gpt4 key购买 nike

考虑以下要点:https://gist.github.com/anonymous/0703a591f97fa9f6ad35b29234805fbd - 没有有效的方式来显示所有相关信息,因为文件相当长。道歉

我有一些我正在尝试解码的嵌套 JSON 对象。

{  
"establishments":[
{ ... }
],
"meta":{ ... },
"links":[

]
}

^ establishments数组包含 Establishment对象

我的代码成功运行到 ViewController.swift 的第 7 行我实际上在使用 Swift 4 的地方 JSONDecode()功能。

ViewController.swift
let jsonURLString = "http://api.ratings.food.gov.uk/Establishments?address=\(self.getPostalCode(place: place))&latitude=\(place.coordinate.latitude.description)&longitude=\(place.coordinate.longitude.description)&maxDistanceLimit=0&name=\(truncatedEstablishmentName[0].replacingOccurrences(of: "'", with: ""))"

guard let url = URL(string: jsonURLString) else { print("URL is invalid"); return }

URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
guard let data = data, error == nil, response != nil else {
print("Something went wrong")
return
}
//print("test")
do {
let establishments = try JSONDecoder().decode(Establishments.self, from: data)
print(establishments)
} catch {
print("summots wrong")
}

}).resume()

我在 Establishment.swift 中看到的映射 JSON 对象的输出是: summots wrong - 第 11 行,共 ViewController.swift .

我相信它没有按预期工作的原因是因为 JSON 格式是这样的:
{  
"establishments":[ ... ],
"meta":{ ... },
"links":[ ]
}

但我不知道我的类结构/我在 View Controller 中所做的事情是否满足此布局标准。

谁能发现我哪里出错了?我认为这是非常基本的东西,但我似乎无法理解它

我也明白我不应该用大写字母来命名类的属性 - 为打破任何约定而道歉

编辑:我打印了错误而不是我自己的语句,如下所示:

而不是: print("summots wrong")
我写道: print(error)
dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.})))

正如 Hamish 正确指出的那样,我没有从 GET 请求中收到正确的 JSON 数据。事实上,我根本没有收到任何 JSON。当 x-api-version 出现时,我使用的 API 默认为 XML 格式。未设置为 2 .

而不是 //print("test")在我的 ViewController.swift文件,我使用了推荐的: print(String(data: data, encoding: .utf8))线

我使用了带有以下标题的 Postman: x-api-version: 2 , accept: application/jsoncontent-type: application/json检索我的 JSON 输出。如果我在浏览器窗口中使用相同的 GET 字符串(正确填写所有参数),我将收到一条错误消息: The API 'Establishments' doesn't exist以 XML 格式。

有什么办法可以让我发送带有此 URL 的 header 吗?

编辑 2:我已更改使用请求 URLRequest而不仅仅是 URL .

这是我更新的 ViewController.swift代码:
let jsonURLString = "http://api.ratings.food.gov.uk/Establishments?address=\(self.getPostalCode(place: place))&latitude=\(place.coordinate.latitude.description)&longitude=\(place.coordinate.longitude.description)&maxDistanceLimit=0&name=\(truncatedEstablishmentName[0].replacingOccurrences(of: "'", with: ""))"

guard let url = URL(string: jsonURLString) else { print("URL is invalid"); return }
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.addValue("x-api-version", forHTTPHeaderField: "2")
request.addValue("accept", forHTTPHeaderField: "application/json")
request.addValue("content-type", forHTTPHeaderField: "application/json")

URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
guard let data = data, error == nil, response != nil else {
print("Something went wrong")
return
}
print(String(data: data, encoding: .utf8))
// do {
// let establishments = try JSONDecoder().decode(Establishments.self, from: data)
// print(establishments)
// } catch {
// print(error)
// }

}).resume()

我收到错误: HTTP Error 400. The request has an invalid header name
我做了一些检查,请求只是忽略了 x-api-version header 值为 2。

有任何想法吗?

编辑 3: addValue 的正确格式本来应该: request.addValue("2", forHTTPHeaderField: 'x-api-version等等。

我现在面临着类声明的问题,特别是在我的“元”类中。
Meta.(CodingKeys in _DF4B170746CD5543281B14E0B0E7F6FB).dataSource], debugDescription: "Expected String value but found null instead.", underlyingError: nil
它在提示是因为我的类声明与它期望的来自 JSON 对象的数据不匹配。

在我的 JSON 响应中(引用要点)有两个 meta对象,一个包含值 nulldataSource另一个是 Lucene .

有什么方法可以让我在类初始值设定项中接受“空”值和字符串,同时遵守可解码协议(protocol)?

JSON 响应的那部分对我来说已经死了,我是否仍然需要为它创建对象,或者我可以忽略它们而逃脱? - 没有声明任何东西。或者我是否特别需要记下 JSON 响应中的所有内容才能使用数据?

最佳答案

要自动解码,您的模型类属性必须与响应值类型匹配。从 JSON 响应中,我可以看到很少有数据模型属性与 JSON 值类型不匹配。例如:

//inside response
"Hygiene": 10, // which is integer type

// properties in Scores
let Hygiene: String

您必须将模型类属性更改为响应或 JSON 响应作为您的类属性。

为了演示,我已通过以下更改修改了您的模型类:
        // changed from String
let Hygiene: Int
let Structural: Int
let ConfidenceInManagement: Int

// changed from Double
let longitude: String
let latitude: String

// changed to optional
let dataSource: String?
let returncode: String?

// changed from Int
let RatingValue: String

用以下更改替换您的模型类:
class Scores: Decodable {
// set as string because we can expect values such as 'exempt'
let Hygiene: Int
let Structural: Int
let ConfidenceInManagement: Int

init(Hygiene: Int, Structural: Int, ConfidenceInManagement: Int) {
self.Hygiene = Hygiene
self.Structural = Structural
self.ConfidenceInManagement = ConfidenceInManagement
}
}

class Geocode: Decodable {
let longitude: String
let latitude: String

init(longitude: String, latitude: String) {
self.longitude = longitude
self.latitude = latitude
}
}

class Meta: Decodable {
let dataSource: String?
let extractDate: String
let itemCount: Int
let returncode: String?
let totalCount: Int
let totalPages: Int
let pageSize: Int
let pageNumber: Int

init(dataSource: String, extractDate: String, itemCount: Int, returncode: String, totalCount: Int, totalPages: Int, pageSize: Int, pageNumber: Int) {

self.dataSource = dataSource
self.extractDate = extractDate
self.itemCount = itemCount
self.returncode = returncode
self.totalCount = totalCount
self.totalPages = totalPages
self.pageSize = pageSize
self.pageNumber = pageNumber
}
}

class Establishments: Decodable {
let establishments: [Establishment]

init(establishments: [Establishment]) {
self.establishments = establishments
}
}

class Establishment: Decodable {
let FHRSID: Int
let LocalAuthorityBusinessID: String
let BusinessName: String
let BusinessType: String
let BusinessTypeID: Int
let AddressLine1: String
let AddressLine2: String
let AddressLine3: String
let AddressLine4: String
let PostCode: String
let Phone: String
let RatingValue: String
let RatingKey: String
let RatingDate: String
let LocalAuthorityCode: Int
let LocalAuthorityName: String
let LocalAuthorityWebSite: String
let LocalAuthorityEmailAddress: String
let scores: Scores
let SchemeType: String
let geocode: Geocode
let RightToReply: String
let Distance: Double
let NewRatingPending: Bool
let meta: Meta
let links: [String]

init(FHRSID: Int, LocalAuthorityBusinessID: String, BusinessName: String, BusinessType: String, BusinessTypeID: Int, AddressLine1: String, AddressLine2: String, AddressLine3: String, AddressLine4: String, PostCode: String, Phone: String, RatingValue: String, RatingKey: String, RatingDate: String, LocalAuthorityCode: Int, LocalAuthorityName: String, LocalAuthorityWebSite: String, LocalAuthorityEmailAddress: String, scores: Scores, SchemeType: String, geocode: Geocode, RightToReply: String, Distance: Double, NewRatingPending: Bool, meta: Meta, links: [String]) {

self.FHRSID = FHRSID
self.LocalAuthorityBusinessID = LocalAuthorityBusinessID
self.BusinessName = BusinessName
self.BusinessType = BusinessType
self.BusinessTypeID = BusinessTypeID
self.AddressLine1 = AddressLine1
self.AddressLine2 = AddressLine2
self.AddressLine3 = AddressLine3
self.AddressLine4 = AddressLine4
self.PostCode = PostCode
self.Phone = Phone
self.RatingValue = RatingValue
self.RatingKey = RatingKey
self.RatingDate = RatingDate
self.LocalAuthorityCode = LocalAuthorityCode
self.LocalAuthorityName = LocalAuthorityName
self.LocalAuthorityWebSite = LocalAuthorityWebSite
self.LocalAuthorityEmailAddress = LocalAuthorityEmailAddress
self.scores = scores
self.SchemeType = SchemeType
self.geocode = geocode
self.RightToReply = RightToReply
self.Distance = Distance
self.NewRatingPending = NewRatingPending
self.meta = meta
self.links = links
}
}

希望它会奏效。

关于json - 解码 JSON 对象(发送带参数的 GET 请求) - Swift 4 Decodable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46915397/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com