Vapor3 JSON编码和解码

时间:2018-07-31 13:37:54

标签: json swift

我必须为项目使用FoundationDB数据库。它将数据存储为存储为字节的key:value对。我想存储一个映射到我拥有的结构的JSON对象。我希望能够将数据另存为编码的JSON对象,然后能够通过从数据库读取值Bytes来重新创建JSON对象。

在我的CreateRecord函数中,我在请求中传递JSON并使用它创建我的Country对象。我需要将数据类型转换为字节以存储它。

到目前为止,我已经提出了这个建议。

let data: Bytes = try JSONEncoder().encode(country).base64URLEncodedString()

然后,当我从数据库中读取记录时,我需要能够逆向此过程,以便从存储JSON的字节中创建Country对象。

let mycountry:Country = try decoder.decode(Country.self, from: Data(bytes: DBrecord.value) )

struct是:

struct Country: Content {
    var country_name: String
    var timezone: String
    var default_PickUp_location: String = ""
    init(country_name: String, timezone:String, default_PickUp_location: String?) {
        self.country_name = country_name
        self.timezone = timezone
        if default_PickUp_location != nil {
            self.default_PickUp_location = default_PickUp_location!
        }
    }
}

示例JSON是:

{ "country_name" : "Denmark", "timezone" : "Europe\/Copenhagen", "default_pickup_location" : "Copenhagen" }

我似乎无法撤销转换。有什么帮助吗?

2 个答案:

答案 0 :(得分:1)

在JSON中,您使用default_pickup_location,在struct中,您使用default_PickUp_location。您需要确定一个版本。

要发现这一点,我使用了以下测试路线:

router.get("json")
{
    request throws -> String in
    let json = "{ \"country_name\" : \"Denmark\", \"timezone\" : \"Europe/Copenhagen\", \"default_pickup_location\" : \"Copenhagen\" }"
    let encoder = try JSONDecoder().decode(Country.self, from: json)
    return "It works"
}

返回:

  

{“错误”:true,“原因”:“密钥所需的值   'default_PickUp_location'。“}

答案 1 :(得分:0)

声明的“字节”类型在哪里,我不认为它是SwiftLang或Foundation Type。我可以重新识别Data(bytes: Array<UInt>)吗?我猜这是一种编码解码类型不一致。另外,为了简化编码和解码到JSON,而又不迅速修改Camel Case,您可以尝试一下。

struct Country: Content {
  let countryName: String
  let timezone: String
  let defaultPickupLocation: String

  enum CodingKeys: String, CodingKey {
    case countryName = "country_name"
    case timezone
    case defaultPickupLocation = "default_pickup_location"
  }
}

出于类型一致性的原因,我进一步建议您从容器中获取编码器和解码器。例如,如果您的所有JSON都变成蛇形,则可以更改容器的编码器和解码器,并从上方跳过编码键枚举。

var encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase

您可以按如下方式从容器中获取编码器和解码器

    let contentCoders: ContentCoders = try worker.make()
    let jsonEncoder = try contentCoders.requireDataEncoder(for: .json) as? JSONEncoder