Swift Json 解码不确定传入数据

Posted

技术标签:

【中文标题】Swift Json 解码不确定传入数据【英文标题】:Swift Json decoding with unsure incoming data 【发布时间】:2022-01-22 19:29:21 【问题描述】:

我正在努力快速解码一些 Json 数据。

我的后端 api 将返回一个 X 数组或一个具有(至少)一个名为“items”的 X 类型数组的属性的对象。

我已搜索但没有找到解决方案。你有吗?

struct A: Decodable 
   var items: [X]
   // some other optional properties

   public init(from decoder: Decoder) throws 
       // Sometimes I receive the correct A object
       // Sometimes I only receive the array of X without the surrounding object of type A.
   

更糟糕的是,我一定会像一直收到类型 A 的对象一样进行解码...:

myObjectOfTypeA = try decoder.decode(A.self, from: data)

大多数时候,我会收到一个像这样的适当的 A 对象:


    "items": 
    [
        
            "id": 7,
            "startsOn": "2021-03-01",
            "endsOn": "2021-12-31"
        ,
        
            "id": 6,
            "startsOn": "2021-04-19",
            "endsOn": "2022-04-04"
        
    ],
    "next": null,
    "prev": null,
    "count": 2

但有时,我只会收到这样的 items 数组:

[
    
        "id": 7,
        "startsOn": "2021-03-01",
        "endsOn": "2021-12-31"
    ,
    
        "id": 6,
        "startsOn": "2021-04-19",
        "endsOn": "2022-04-04"
    
]

任何想法都将不胜感激,因为我自己显然没有想法...... ????

【问题讨论】:

使用quicktype.io。两种情况都有路径,它会生成解析代码 您能否添加一个与您所描述的内容相匹配的 json 样本? 那是你的 JSON 的顶层吗?您需要下一个/上一个/计数值吗? 是的,我发布的 json 是我可以接收的两个可能的*** json。 next/previous/count 属性由后端提供,即使它们对我来说不是强制性的。 如果您为不同的端点获得两个不同的 JSON 字符串,那么 incoming data 非常 sure 并且您可以使用泛型类型。 【参考方案1】:

您只需要尝试解码您的封闭类型项目并捕获错误。如果是类型不匹配错误,请尝试再次对其进行解码。无需创建自定义解码器:


struct A: Decodable 
   let items: [X]


struct X: Decodable 
    let id: Int
    let startsOn: Date
    let endsOn: Date


游乐场测试:

let json = """

    "items":
    [
        
            "id": 7,
            "startsOn": "2021-03-01",
            "endsOn": "2021-12-31"
        ,
        
            "id": 6,
            "startsOn": "2021-04-19",
            "endsOn": "2022-04-04"
        
    ],
    "next": null,
    "prev": null,
    "count": 2

"""

let dateFormatter = DateFormatter()
dateFormatter.calendar = .init(identifier: .iso8601)
dateFormatter.locale = .init(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd"

let jsonDecoder = JSONDecoder()
jsonDecoder.dateDecodingStrategy = .formatted(dateFormatter)
let items: [X]
do 
    items = try jsonDecoder.decode(A.self, from: Data(json.utf8)).items
 catch DecodingError.typeMismatch 
    items = try jsonDecoder.decode([X].self, from: Data(json.utf8))
 catch 
    items = []
    print(error)

print(items)

它将为两个 json 输入打印以下内容:

[X(id:7,startsOn:2021-03-01 03:00:00 +0000,endsOn:2021-12-31 03:00:00 +0000),X(id:6,startsOn:2021 -04-19 03:00:00 +0000,结束时间:2022-04-04 03:00:00 +0000)]

【讨论】:

非常感谢你们。最新的解决方案对我有用。我试图避免尝试捕获,因为它可能很耗时,但在我被告知相反的情况之前,我会认为这对我来说很好。谢谢大家的帮助??? @jbat 欢迎您。你知道如何将答案标记为正确吗? 好吧,我搜索了一下,但没有成功。也许它太明显了,就在我眼前,我看不到它?。有什么提示吗?

以上是关于Swift Json 解码不确定传入数据的主要内容,如果未能解决你的问题,请参考以下文章

Swift 中的 JSON 解码。无法读取数据,因为它的格式不正确

如何在 Swift 中解码这个 JSON 数据?

通过使用 Alamofire 和解码获取 JSON - Swift 4

Swift 4 Decodable - 将 JSON 对象解码为“数据”

Swift - 使用 JSONDecoder 解码 JSON 数据

Swift - 解码数组 JSON 数据的数组