如何使用Swift Decodable协议解析JSON API结构中的几个硬编码键?

时间:2018-06-05 18:50:03

标签: json swift parsing swift4

问题:我正在尝试解码我​​的JSON,其中一些JSON将具有随机字符串,而一些将具有硬编码字符串。当硬编码字符串是下面的一个时,我想显示不同的UICollectionView单元格。如果它是一个硬编码字符串并且能够显示不同的UICollectionViewCell,我在尝试解析我的JSON时遇到了麻烦。对此的任何帮助都会很棒。这可能是一个初学者的问题但我过去一周试图解决这个问题而且我在尝试这样做时遇到了麻烦。任何有关这方面的帮助将非常感激。

**  Hardcoded Strings that could be one or the other:**
key: --> This string could be "breaking" or "normal" or "new"
item: --> This string could be "placement" or "slot" or "shared"
verb: --> This string could be "shared" or "posted"

** NOT hardcoded strings, which the string comes in randomly**
heading: --> This string is a random string
type: --> This string is a random string

这是我的一些JSON,所以你可以得到我想要做的一个例子:

    {
    slots: [
        {
        key: "breaking",
        item: "placement",
        heading: "Random String Text",
        type: "Random String Text",
        via: "Random",
        verb: "shared"
        sort_order: 0
        },
        {
        key: "breaking",
        item: "placement",
        heading: "Random String Text",
        type: "Random String Text",
        via: "Random",
        verb: "posted"
        sort_order: 1
        },
        {
        key: "event",
        item: "combine",
        heading: "Random String Text",
        type: "Random String Text",
        via: "Random",
        verb: "posted"
        sort_order: 2
        },
}

到目前为止,这是我的模型:

struct MyModel: Decodable {
    var key: String?
    var item: String?
    var heading: String?
    var type: String?
    var via: String?
    var verb: String?
}

这是Dmitry Serov帮助我的一个示例单元格。

func collectionView(_ collectionView: UICollectionView,
 cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

   let model = ... // retrieve your model object here
   if model.verb == .shared {
     // Pass the pertinent identifier
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier:...)
     return cell
   else {
     ....
   }
 }

这是Dmitry Serov帮助我的更多代码。

struct MyModel { // Type names should use pascal case in Swift
  var verb: State?
  ....
  enum State {
    case shared
    case posted
  }
}

// Decode your enums from strings
extension MyModel.State: Decodable {
  enum CodingKeys: String, CodingKey {
    case shared
    case posted
  }
}

当我尝试上述问题时,问题是要求我输入下面的格式,我不知道该怎么做,我想解析几个键。

extension MyModel.State: Decodable {
    init(from decoder: Decoder) throws {

  }
}

1 个答案:

答案 0 :(得分:0)

这是我使用codable解码你的json的方式:

struct Response: Codable {
    var slots = [Slots]()
}

struct Slots: Codable {
    var key: String?
    var item: String?
    var heading: String?
    var type: String?
    var via: String?
    var verb: String?
    var order: String?

    enum CodingKeys: String, CodingKey {
        case order = "sort_order"
    }
    /** Custom Encoder to send null values**/
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)

        try? container.encode(order, forKey: .order)
    }

}

要与硬编码字符串进行比较,请创建一个枚举:

enum key: String {
    case breking
    case normal
    case new
}

像这样使用它:

if let response = try? JSONDecoder().decode(Response.self, from: response.data!){
for slot in response.slots{
    if slot.key == key.breaking.rawValue{
    //do something
    }
}
}