当前位置: 首页 > 面试题库 >

Swift 4 JSON Codable-返回的值有时是一个对象,其他则是数组

易琛
2023-03-14
问题内容

我从API获取的数据返回一个对象,但是当有多个对象时,它将在同一键中返回一个数组。使用我正在使用的当前模型(结构),显示数组时解码失败。

这些结果是随机排序的,这意味着我不知道何时将对象或数组提供给我。

有没有一种方法可以创建一个模型,该模型考虑到这一事实,并且可以为值(“ String”或“
[String]”)分配正确的类型以进行转换,从而继续解码而不会出现问题?

这是返回对象的示例

{
    "firstFloor": {
        "room": "Single Bed"
    }
}

这是返回数组(针对同一键)的示例:

{
    "firstFloor": {
        "room": ["Double Bed", "Coffee Machine", "TV", "Tub"]
    }
}

应该 能够用作上述两个样本的模型的结构示例:

struct Hotel: Codable {
    let firstFloor: Room

    struct Room: Codable {
        var room: String // the type has to change to either array '[String]' or object 'String' depending on the returned results
    }
}

这些结果是随机排序的,这意味着我不知道何时将对象或数组提供给我。

这是完整的游乐场文件:

import Foundation

// JSON with a single object
let jsonObject = """
{
    "firstFloor": {
        "room": "Single Bed"
    }
}
""".data(using: .utf8)!

// JSON with an array instead of a single object
let jsonArray = """
{
    "firstFloor": {
        "room": ["Double Bed", "Coffee Machine", "TV", "Tub"]
    }
}
""".data(using: .utf8)!

// Models
struct Hotel: Codable {
    let firstFloor: Room

    struct Room: Codable {
        var room: String // the type has to change to either array '[String]' or object 'String' depending on the results of the API
    }
}

// Decoding
let decoder = JSONDecoder()
let hotel = try decoder.decode(Hotel.self, from: jsonObject) //

print(hotel)

问题答案:

您可以使用带有关联值的枚举(在这种情况下为字符串和数组)封装结果的歧义,例如:

enum MetadataType: Codable {
    case array([String])
    case string(String)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        do {
            self = try .array(container.decode(Array.self))
        } catch DecodingError.typeMismatch {
            do {
                self = try .string(container.decode(String.self))
            } catch DecodingError.typeMismatch {
                throw DecodingError.typeMismatch(MetadataType.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Encoded payload not of an expected type"))
            }
        }
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .array(let array):
            try container.encode(array)
        case .string(let string):
            try container.encode(string)
        }
    }
}

struct Hotel: Codable {
    let firstFloor: Room

    struct Room: Codable {
        var room: MetadataType
    }
}


 类似资料:
  • 我知道这里有类似的问题,但是使用这些方法只返回一个max值。我需要的是确定数组的哪些对象在给定属性中具有最大值,并返回在给定属性中具有最大值的那些对象中的某个(其他)属性的值。 我有一个名为week的对象数组,具有两个属性“name”和“traffic”: 在本例中,Monday和Friday属性“traffic”的最大值为13,如果只有一天,我需要返回一个包含具有最高“traffic”值的日期名

  • 从数据库中提取博客。 为什么这里的blogContent在函数的上下文中是全局的,而我们正在内部更改它,所以它应该返回值,有人能解释为什么会这样吗? 有没有不使用promise/async/await的方法>>>有人给了我答案 我如何从异步调用返回响应? 但这一点我不知道,最主要的是我不知道Ajax。

  • 问题内容: 这个问题基本上是不言而喻的。我无法找到用于数组的API(除了此Arrays之外,但这仅定义了一堆用于处理实际数组的静态辅助函数)。如果没有它的类,这似乎表明数组不能是。 然而,事实上,一个阵列具有公共领域,如和方法,它可以调用像和似乎暗示(强烈)相反完整。 对原始数组的奇数表示和行为有何解释? 作为说明,我现在尝试在数组的方法上使用“开放实现” Eclipse功能,希望我能够查看定义此

  • 本文向大家介绍请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1 相关面试题,主要包含被问及请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1 时的应答技巧和注意事项,需要的朋友参考一下   剖析:嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。采用Littl

  • 问题内容: 我正在尝试为通过map函数创建的自定义组件创建动态引用。 在返回正确的DOM节点,但在循环的那些,它返回一个对象。 有人可以指出我正确的方向吗? 问题答案: 似乎是一个连接的组件,而您实际上需要包装的组件。 与连接 然后通常添加一个引用: 从文档: 如果已传递给,则向连接的包装器组件添加一个ref实际上将返回被包装组件的实例。 与连接 然后用于获取基础的连接组件: 从文档: [with

  • 我在Hibernate中遇到了一个奇怪的问题。有两个数据库表存储活动票据和已解析票据。在Java中有一个超类(Ticket)和实体子类(ActiveTicket和ResolvedTicket)。 现在,当解析票据时,它将被移动到ResolvedTicket表。 现在我有了一个定制的findByID方法,我尝试首先检索活动票据,然后如果我有一个null对象,那么我尝试检索已解析票据。看起来是这样的: