大家,如果字段之一未知,如何序列化json结构?
我的 json 是:
{"brands":{"any":false,"19":{"is_all":false,"values":[185,182,178],"include":true},"23":{"is_all":false,"values":[198,199,201],"include":true}},"price":[2000,10000],"year":[1990,2018],"fuel_type":[1,2],"engine_capacity":[\"1.8\",\"4.8\"],"color":[1,2,3],"gearbox_id":[2],"is_georgia":false}
Run Code Online (Sandbox Code Playgroud)
但:
"19":{"is_all":false,"values":[185,182,178],"include":true}
"23":{"is_all":false,"values":[198,199,201],"include":true}
19 和 23 - 是字符串未知值,由 API 生成。
所以我的结构是:
struct auto_order_model: Decodable {
var brands: brand_details <---- this is problem
let price: [Int]
let year: [Int]
let fuel_type: [Int]
let engine_capacity: [String]
let color: [Int]
let gearbox_id: [Int]
let is_georgia: Bool
}
struct brand_details: Decodable {
var any: Bool
var brand_num: [models]?
}
struct models: Decodable {
var is_all: Bool
var values: [Int]
var include: Bool
}
Run Code Online (Sandbox Code Playgroud)
我像这样解码这个json:
do {
let data = …Run Code Online (Sandbox Code Playgroud) 说JSON看起来像这样:
[
{
"name": "Spot",
"breed": "dalmation"
},
{
"color": "green",
"eats": "lettuce"
},
{
"color": "brown",
"eats": "spinach"
},
{
"color": "yellow",
"eats": "cucumbers"
}
]
Run Code Online (Sandbox Code Playgroud)
从API返回的JSON响应中的第一项始终是狗,而之后的所有项都是乌龟.因此项目0是狗,项目1到N-1是海龟.
我如何将其解析为我可以阅读的内容,例如:
struct Result: Codable {
let dog: Dog
let turtles: [Turtle]
}
Run Code Online (Sandbox Code Playgroud)
可能吗?
这是我的场景:我有一个快速的 WebSocket 服务器和一个 Javascript 客户端。通过同一个 WebSocket,我将发送对应于不同Codable 类型的各种对象。如果已知正确的类型,则解码很简单。对我来说,困难在于确定客户端发送的是哪种类型。我的第一个想法是使用如下所示的 JSON:
{type: "GeoMarker",
data: {id: "2",
latitude: "-97.32432"
longitude: "14.35436"}
}
Run Code Online (Sandbox Code Playgroud)
这样我就知道使用解码data这let marker = try decoder.decode(GeoMarker.self)
似乎很简单,但由于某种原因,我只是不知道如何将对象提取data为 JSON,以便我可以使用 GeoMarker 类型对其进行解码。
我想出的另一个解决方案是创建一个中间类型,如下所示:
struct Communication: Decodable {
let message: String?
let markers: [GeoMarker]?
let layers: [GeoLayer]?
}
Run Code Online (Sandbox Code Playgroud)
这样我就可以发送以下格式的 JSON:
{message: "This is a message",
markers: [{id: "2",
latitude: "-97.32432"
longitude: "14.35436"},
{id: "3",
latitude: "-67.32432"
longitude: "71.35436"}]
}
Run Code Online (Sandbox Code Playgroud)
并使用let com = try decoder.decode(Communication.self)和解包可选的消息、标记和图层变量。这可行,但看起来很笨重,特别是当我需要更多类型时。说完一切之后,我可能最终需要 8-10 个。
我已经考虑过这个问题,但我觉得我没有想出一个令人满意的解决方案。会有更好的方法吗?对于我不知道的这种事情是否有一个标准? …
这是我的JSON响应值:
{
"_embedded": {
"task": [
{
"_embedded": {
"variable": [
{
"_links": {
"self": {
"href": "/process-instance/412a03b7-06ae-11ea-8860-120ef5ab2c25/variables/loanAmount"
}
},
"_embedded": null,
"name": "loanAmount",
"value": "650000",
"type": "String",
"valueInfo": {}
}
]
},
"id": "412a2aca-06ae-11ea-8860-120ef5ab2c25",
"name": "Quick Evaluation",
"assignee": "demo",
"created": "2019-11-14T07:13:27.558+0000",
"processDefinitionId": "quickEvaluation:1:129ce2b1-0616-11ea-8860-120ef5ab2c25"
}
]
},
"count": 13
}
Run Code Online (Sandbox Code Playgroud)
这是struct可编码的代码:
import Foundation
public struct TaskID: Codable {
let embedded: Embedded
}
public struct Embedded: Codable {
let task: [Task]
}
public struct Task : Codable {
let embedded: EmbeddedVariable …Run Code Online (Sandbox Code Playgroud) 后端返回位置的自定义 JSON 值。如示例所示:
{
"location": (54.000000, 21.000000)
}
Run Code Online (Sandbox Code Playgroud)
为了解析 JSON,我使用以下代码:
let json = """
{
"location": (54.000000, 21.000000)
}
"""
struct Location: Codable {
var latitude: Double
var longitude: Double
}
let dataJson = json.data(using: .utf8)!
let location = try? JSONDecoder().decode(Location.self, from: dataJson)
Run Code Online (Sandbox Code Playgroud)
当我尝试使用 JSONDecoder 创建 Location 对象时,出现错误:给定的数据不是有效的 JSON。
dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 18." UserInfo={NSDebugDescription=Invalid value around character 18.})))
Run Code Online (Sandbox Code Playgroud)
我知道它不是有效的 JSON。重写哪些方法可以解析无效的 JSON 值?
我使用以下解码结构来解码来自服务器的数据,但它总是返回“没有与密钥 CodingKeys 关联的值”。请看下面的代码
struct UserDecode: Codable {
var user: User?
var result: String?
private enum CodingKeys: String, CodingKey {
case user = "Records"
case result = "Result"
}
init(from decoder: Decoder) throws {
do {
let values = try decoder.container(keyedBy: CodingKeys.self)
result = try values.decode(String.self, forKey: .result)
user = try values.decode(User.self, forKey: .user)
} catch {
print(error.localizedDescription)
}
}
}
struct User: Codable {
var mobile: Int?
var userId: Int?
var name: String?
private enum CodingKeys: String, CodingKey {
case …Run Code Online (Sandbox Code Playgroud) 我实现 JSONDecoder 以从 Wordpress json 获取 JSON 数据,我的结构位于另一个 swift 文件中,我收到此错误,这是我的代码。在让文章上我收到错误
URLSession.shared.dataTask(with: url!){ (data,response ,err) in
guard let data = data else{return}
let article = JSONDecoder.decode(LatestArticleModel , from: data)
}.resume()
Run Code Online (Sandbox Code Playgroud)
最新文章模型.swift
struct LatestArticleModel : Decodable {
var id: Int
var date: String
var link: String
var title_rendered :String
var author: Int
var category: Int
var img_link: String
var content_rendered: String
var exerpt_rendered: String
}
Run Code Online (Sandbox Code Playgroud) 我有一个通用的 JSON 解析器,可以解码数组
class JSONParserFromStruct {
typealias result<T> = (Result<[T], Error>) -> Void
func downloadList<T: Decodable>(of _: T.Type,
from data: Data,
completion: @escaping result<T>) {
do {
let decodedData: [T] = try! JSONDecoder().decode([T].self, from: data)
completion(.success(decodedData))
} catch {
completion(.failure(DataError.decodingError))
}
}
}
Run Code Online (Sandbox Code Playgroud)
捆绑包中的 Users.json 文件
{
"name": "Taylor Swift"
}
Run Code Online (Sandbox Code Playgroud)
像这样调用它:
func performRequest() {
let url = Bundle.main.url(forResource: "Users", withExtension: "json")!
let data = try! Data(contentsOf: url)
genericParser.downloadList(of: User.self, from: data) { result in
switch result {
case let …Run Code Online (Sandbox Code Playgroud) 我有以下 JSON 对象:
{
"user_name":"Mark",
"user_info":{
"b_a1234":"value_1",
"c_d5678":"value_2"
}
}
Run Code Online (Sandbox Code Playgroud)
我已经JSONDecoder这样设置了:
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
Run Code Online (Sandbox Code Playgroud)
我的Decodable对象看起来像这样:
struct User: Decodable {
let userName: String
let userInfo: [String : String]
}
Run Code Online (Sandbox Code Playgroud)
我面临的问题是该.convertFromSnakeCase策略正在应用于字典的键,我希望这种情况不会发生。
// Expected Decoded userInfo
{
"b_a1234":"value_1",
"c_d5678":"value_2"
}
// Actual Decoded userInfo
{
"bA1234":"value_1",
"cD5678":"value_2"
}
Run Code Online (Sandbox Code Playgroud)
我研究过使用自定义keyDecodingStrategy(但没有足够的信息来以不同方式处理字典)以及我的自定义初始值设定项Decodable结构的自定义初始值设定项(似乎此时键已经被转换)。
处理此问题的正确方法是什么(仅为字典创建键转换异常)?
注意:我更愿意保留蛇形大小写转换策略,因为我的实际 JSON 对象在蛇形大小写中有很多属性。我当前的解决方法是使用 CodingKeys 枚举手动进行蛇形大小写转换。
我有一个 JSON,其 ID 在根级别:
{
"12345": {
"name": "Pim"
},
"54321": {
"name": "Dorien"
}
}
Run Code Online (Sandbox Code Playgroud)
我的目标是使用 Codable 创建一个同时具有 name 和 ID 属性的 User 对象数组。
struct User: Codable {
let id: String
let name: String
}
Run Code Online (Sandbox Code Playgroud)
我知道如何使用带有单个根级别密钥的Codable ,并且知道如何使用未知密钥。但我在这里尝试做的是两者的结合,我不知道下一步该做什么。
这是我到目前为止得到的:(您可以将其粘贴到 Playground 中)
import UIKit
var json = """
{
"12345": {
"name": "Pim"
},
"54321": {
"name": "Dorien"
}
}
"""
let data = Data(json.utf8)
struct User: Codable {
let name: String
}
let decoder = JSONDecoder() …Run Code Online (Sandbox Code Playgroud)