当前位置: 首页 > 知识库问答 >
问题:

如何在swift中对不同数据类型密钥进行解码

尉迟宪
2023-03-14

我在用Swift将json解码成可编码模型时遇到了一些问题。 从服务器获得的json响应如下所示

{
  "code": 200,
  "data": {
    "Australia": {
      "address": "1111",
      "port": "443",
      "proto": "udp",
      "country": "au"
    },
    "Australia udp": {
      "address": "2222",
      "port": "443",
      "proto": "udp",
      "country": "au"
    },
    "Vietnam TCP": {
      "address": "3333",
      "port": "443",
      "proto": "tcp",
      "country": "vn"
    },
    "status": "1"
  }
}

现在我找到了其他关于如何解码简单数据类型的帖子,但是我没有找到解码复杂数据类型的帖子! 到目前为止我所做的就是这个模型

struct ListServers: Codable {
    let code: Int
    let data: [String: ListServersData]
}

enum ListServersData: Codable {
    case string(String)
    case innerItem(ServerInfo)
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        if let x = try? container.decode(ServerInfo.self) {
            self = .innerItem(x)
            return
        }
        throw DecodingError.typeMismatch(ListServersData.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for MyValue"))
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .string(let x):
            try container.encode(x)
        case .innerItem(let x):
            try container.encode(x)
        }
    }
}

struct ServerInfo: Codable {
    let address, port, proto, country: String
}

但这会抛出一个错误!!

我不确定如何解码,因为我有响应的附加状态

共有1个答案

徐昊焜
2023-03-14

请尝试以下操作:

只需在某处设置一个json字符串

let json =
"""
{
  "code": 200,
  "data": {
    "Australia": {
      "address": "1111",
      "port": "443",
      "proto": "udp",
      "country": "au"
    },
    "Australia udp": {
      "address": "2222",
      "port": "443",
      "proto": "udp",
      "country": "au"
    },
    "Vietnam TCP": {
      "address": "3333",
      "port": "443",
      "proto": "tcp",
      "country": "vn"
    },
    "status": "1"
  }
}
"""

然后设置与上面相同的结构和枚举:

struct ListServers: Codable {
    let code: Int
    let data: [String: ListServersData]
}

enum ListServersData: Codable {
    case string(String)
    case innerItem(ServerInfo)
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        if let x = try? container.decode(ServerInfo.self) {
            self = .innerItem(x)
            return
        }
        throw DecodingError.typeMismatch(ListServersData.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for MyValue"))
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .string(let x):
            try container.encode(x)
        case .innerItem(let x):
            try container.encode(x)
        }
    }
}

struct ServerInfo: Codable {
    let address, port, proto, country: String
}

然后像这样解码json:

let jsonData = json.data(using: .utf8)!

do {
    let decoder = JSONDecoder()
    let result = try decoder.decode(ListServers.self, from: jsonData)
    print("Code: \(result.code)")
    
    for (_, v) in result.data {
        switch v {
        case .string(let string):
            print("Status: \(string)")
            
        case .innerItem(let serverInfo):
            print("Address: \(serverInfo.address)")
            print("Port: \(serverInfo.port)")
            print("Proto: \(serverInfo.proto)")
            print("Country: \(serverInfo.country)")
        }
        
        print("=======================")
    }
}
catch {
    print(error)
}

这就是正确打印出来的内容:

Code: 200
Address: 3333
Port: 443
Proto: tcp
Country: vn
=======================
Address: 2222
Port: 443
Proto: udp
Country: au
=======================
Status: 1
=======================
Address: 1111
Port: 443
Proto: udp
Country: au
=======================
 类似资料:
  • 我正在尝试使用RSA和OAEPPadding对实际更大的数据(比如10 KB)执行非对称加密和解密。 许多Stackoverflow文章提到使用混合方法[不对称对称],但我并不是在寻找这种方法。我故意要求非对称加密。 我初始化加密和解密密码如下: 下面是我试图加密或解密大小为10 KB的大数据的代码。 以下是我收到的例外情况: 请告诉我如何对大数据执行RSA加密和解密。

  • 问题内容: 我想生成rsa密钥对(公共和私有),然后将它们用于AES加密和解密。例如,用于加密的公共密钥和用于解密的私有密钥。我为此编写了一个简单的代码,但是问题是当我运行时这段代码我得到这个错误: 我该如何解决这个问题?我的加密代码如下: 问题答案: 如评论中所建议,我搜索了“混合密码术”。这个例子解决了我的问题。

  • 问题内容: 考虑以下是我的数组 创建了它,就像下面的代码一样: 现在,我正在尝试根据字段进行排序。 所需输出: 关于Java&Gson,谁能以最好的方式帮助解决这个问题? 非常感谢您的投入。 问题答案: 首先,解析JSON的正确方法是创建一个类来封装数据,例如: 然后: 现在您有了一个,并且想要按属性的值对其进行排序,因此可以按照此处的说明使用: 最后:

  • 问题内容: 可以说我有: 我想实现allEqual()函数作为扩展,所以我可以做 问题答案: 可以说具体类型是S CollectionType协议

  • 我正在通过Java查询一个MySQL数据库,从结果集中提取数据并将其放入DefaultTableModel,该Model被放入JTable,然后被放入JScrollPane中显示。 以下是该类的源代码:

  • 问题内容: 如何在Swift中随机或随机排列数组中的元素?例如,如果我的阵列由52张扑克牌,我想 洗牌 的阵列,以洗牌。 问题答案: 该答案详细说明了如何在Swift 4.2+中使用快速统一的算法(Fisher- Yates)进行改组,以及如何在各个早期版本的Swift中添加相同功能。每个Swift版本的命名和行为都与该版本的变异和非变异排序方法匹配。 并且是从Swift 4.2开始原生的 用法示

  • 我想用python实现下面的功能,它使用公钥加密密码,然后使用base 64进行编码。我搜索了许多答案,但没有找到解决方案,我想可能是我不明白。请给我一些建议好吗? 我使用以下代码,但它会引发错误。

  • 我正在用C语言开发一种象棋游戏,只是为了练习。在游戏开始时,用户可以键入4样东西: ROW