标签: codable

使用具有多个键的可解码协议

假设我有以下代码:

import Foundation

let jsonData = """
[
    {"firstname": "Tom", "lastname": "Smith", "age": {"realage": "28"}},
    {"firstname": "Bob", "lastname": "Smith", "age": {"fakeage": "31"}}
]
""".data(using: .utf8)!

struct Person: Codable {
    let firstName, lastName: String
    let age: String?

    enum CodingKeys : String, CodingKey {
        case firstName = "firstname"
        case lastName = "lastname"
        case age
    }
}

let decoded = try JSONDecoder().decode([Person].self, from: jsonData)
print(decoded)
Run Code Online (Sandbox Code Playgroud)

一切都在工作,除了age总是nil。这是有道理的。我的问题是如何在第一个示例和第二个示例中设置人的年龄 =realage或。取而代之的是在这两种情况下,我想这是在第一种情况。28nilagenil28

有没有办法只使用CodingKeys而不必添加另一个结构或类来实现这一点?如果不是,我如何使用另一个结构或类以最简单的方式实现我想要的?

json swift swift4 codable

1
推荐指数
1
解决办法
1992
查看次数

制作符合 Codable 的对象的(深层)副本

我有一个对象,它Object是 Realm 的子类,并且Codable在与 API 交谈时符合JSON 的要求。

如何利用Codable协议制作深度副本(包括子对象)?

realm ios swift codable

1
推荐指数
1
解决办法
1777
查看次数

Swift 4 可解码多个容器

我试图了解如何将这个多容器 JSON 解析为一个对象。我已经尝试过这种方法(Mark answer),但他解释了如何使用一级容器解决它。出于某种原因,我无法模仿多个容器的行为。

 {
     "graphql": {
        "shortcode_media": {
          "id": "1657677004214306744",
          "shortcode": "BcBQHPchwe4"
        }
     }
  }
Run Code Online (Sandbox Code Playgroud)
class Post: Decodable {


    enum CodingKeys: String, CodingKey {
        case graphql // The top level "user" key
        case shortcode_media
    }

    enum PostKeys: String, CodingKey {
        case id
    }

    required init(from decoder: Decoder) throws {

        let values = try decoder.container(keyedBy: CodingKeys.self)

        let post = try values.nestedContainer(keyedBy: PostKeys.self, forKey: .shortcode_media)

        self.id = try post.decode(String.self, forKey: .id)

    }

    var id: String

}
Run Code Online (Sandbox Code Playgroud)

我越来越:

Swift.DecodingError.Context(codingPath: [], …
Run Code Online (Sandbox Code Playgroud)

containers json swift4 codable decodable

1
推荐指数
1
解决办法
2175
查看次数

Swift 4.1 Decodable 无法使用nestedContainer 解码嵌套数组

尝试编写一个简单的Swift 4.1使用 Codable 来解析json.

我有一个struct这样的:

struct GameCharacter : Codable {
  var name : String
  var weapons : [Weapon]
  enum CodingKeys : String, CodingKey {
    case name
    case weapons
  }

  init(from decoder: Decoder) {
    do {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.name = try container.decode(String.self, forKey: .name)
        let weaponsContainer = try container.nestedContainer(keyedBy: Weapon.CodingKeys.self, forKey: .weapons)
        self.weapons = try weaponsContainer.decode([Weapon].self, forKey: .weapons)

    } catch let error {
        print("error: \(error)")
        fatalError("error is \(error)")
    }
  }
} …
Run Code Online (Sandbox Code Playgroud)

ios swift codable

1
推荐指数
1
解决办法
2244
查看次数

使用 Codable 问题解码 JSON。keyNotFound 错误信息

我在解码 JSON 时遇到问题。我正在尝试解码我​​的 JSON

let temp = try JSONDecoder().decode([LastTemperatureResponse].self, from: data).

我的Codable结构如下:

struct LastTemperatureResponseElement: Codable {
    let measurement: Measurement
}

struct Measurement: Codable {
    let ts: String
    let sensors: [VportSensor]
}

struct VportSensor: TemperatureSensor, Codable {
    var lastUpdate: String!

    let address, description: String
    let status: String
    let temperature: Double
} 
Run Code Online (Sandbox Code Playgroud)

好吧,如果我试图解码我的 JSON,我会收到很清楚的错误消息

keyNotFound(CodingKeys(stringValue: "status", intValue: nil), Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "measurement", intValue: nil), CodingKeys(stringValue: "sensors", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No …
Run Code Online (Sandbox Code Playgroud)

json swift codable

1
推荐指数
1
解决办法
1万
查看次数

字段级自定义解码器

我正在尝试实现字段级自定义解码,以便可以提供解码器功能来映射值。这最初是为了解决将“Y”和“N”的字符串值自动转换为真/假的问题。有没有更简洁的方法可以做到这一点?

这旨在用于一个相当不错的大小记录的单个字段......但有点失控。

主要目标不是必须手动实现记录中每个字段的解码,而是枚举它们并将默认解码器的结果用于没有自定义解码器的任何内容(这可能不应该被称为“解码器”)。

当前尝试如下所示:

class Foo: Decodable {
    var bar: String
    var baz: String

    init(foo: String) {
        self.bar = foo
        self.baz = ""
    }

    enum CodingKeys: String, CodingKey {
        case bar
        case baz
    }

    static func customDecoder(for key: CodingKey) -> ((String) -> Any)? {
        switch key {
        case CodingKeys.baz: return { return $0 == "meow" ? "foo" : "bar" }
        default:
            return nil
        }
    }

    required init(from decoder: Decoder) throws {
        let values: KeyedDecodingContainer = try decoder.container(keyedBy: CodingKeys.self)

        if let …
Run Code Online (Sandbox Code Playgroud)

swift codable

1
推荐指数
1
解决办法
703
查看次数

Swift 解码具有多种不同格式的数据类型

我从服务器返回了一个“几种”不同格式的布尔值(对于相同的结构和字段)。我知道这很荒谬,但我需要找到一种方法来干净地处理它。

所以为了反序列化它,我做了一些类似(示例程序)的事情:

import Foundation

struct Foo: Codable {
    var isOpen: Bool?

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        isOpen = try container.decodeIfPresent(Bool.self, forKey: .isOpen)
    }

    enum CodingKeys: String, CodingKey {
        case isOpen
    }
}

//He sends any one of these..
let json1 = "{ \"isOpen\": \"true\" }"
let json2 = "{ \"isOpen\": \"false\" }"
let json3 = "{ \"isOpen\": true }"
let json4 = "{ \"isOpen\": false }"
let json5 = "{ \"isOpen\": null }"
let …
Run Code Online (Sandbox Code Playgroud)

ios codable decodable swift4.2

1
推荐指数
1
解决办法
1367
查看次数

快速将 Codable/Encodable 转换为 JSON 对象

最近我加入Codable了一个项目并JSON从符合Encodable我的类型中获取一个对象,我想出了这个扩展,

extension Encodable {

    /// Converting object to postable JSON
    func toJSON(_ encoder: JSONEncoder = JSONEncoder()) -> [String: Any] {
        guard let data = try? encoder.encode(self),
              let object = try? JSONSerialization.jsonObject(with: data, options: .allowFragments),
              let json = object as? [String: Any] else { return [:] }
        return json
    }
}
Run Code Online (Sandbox Code Playgroud)

这很有效,但有没有更好的方法来实现同样的目标?

ios swift codable encodable

1
推荐指数
2
解决办法
5092
查看次数

如何解码具有多个在 Swift 中未命名的列表的 JSON

我正在尝试解码一个 JSON 字符串,但它似乎有多个列表,这些列表没有我可以用我的结构调用的任何名称/键。据我所知(仅凭我的一点知识)在这个 JSON 中有两个列表,我只想要第二个列表。我知道如何解码普通的 JSON,但弄清楚如何调用这个无键列表/数组令人困惑。

我试图让我的结构使用 0 或 1,具体取决于我想要的列表,作为案例名称,但这也不起作用。我真的只是对如何调用未明确命名的东西感到困惑。下面是我的 JSON 数据和代码。

这是 JSON 的一小部分:

[{
    "page": 1,
    "pages": 1,
    "per_page": "5000",
    "total": 58
  },
  [{
    "indicator": {
        "id": "NY.GDP.MKTP.CD",
        "value": "GDP (current US$)"
    },
    "country": {
        "id": "US",
        "value": "United States"
    },
    "value": "19390604000000",
    "decimal": "0",
    "date": "2017"
  },
  {
    "indicator": {
        "id": "NY.GDP.MKTP.CD",
        "value": "GDP (current US$)"
    },
    "country": {
        "id": "US",
        "value": "United States"
    },
    "value": "18624475000000",
    "decimal": "0",
    "date": "2016"
  }]
 ]
Run Code Online (Sandbox Code Playgroud)

这是我的 Swift 代码:

    let …
Run Code Online (Sandbox Code Playgroud)

arrays json struct swift codable

1
推荐指数
1
解决办法
899
查看次数

解码有时可能会改变的数据

我有一个名为Info的结构,该结构根据接收到的数据进行解码。但是有时,数据中的值之一可以是double或double数组。我该如何设置我的结构?

这是我的结构:

struct Info: Decodable {

    let author: String
    let title: String
    let tags: [Tags]
    let price: [Double]

    enum Tags: String, Decodable {
        case nonfiction
        case biography
        case fiction
    }

}
Run Code Online (Sandbox Code Playgroud)

根据网址,我要么获得双倍价格

{
    "author" : "Mark A",
    "title" : "The Great Deman",
    "tags" : [
      "nonfiction",
      "biography"
    ],
    "price" : "242"

}
Run Code Online (Sandbox Code Playgroud)

或者我将其作为双打数组获得

{
    "author" : "Mark A",
    "title" : "The Great Deman",
    "tags" : [
      "nonfiction",
      "biography"
    ],
    "price" : [
    "242",
    "299",
    "335"
    ]

}
Run Code Online (Sandbox Code Playgroud)

我想设置我的结构,以便如果我收到一个double而不是double数组,则price应该解码为1 double的数组。

任何帮助将不胜感激。 …

swift swift4 codable decodable

1
推荐指数
1
解决办法
49
查看次数

标签 统计

codable ×10

swift ×8

ios ×4

json ×4

decodable ×3

swift4 ×3

arrays ×1

containers ×1

encodable ×1

realm ×1

struct ×1

swift4.2 ×1