亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Swift 4可解碼協議中如何使用JSON字典類型解碼屬性

Swift 4可解碼協議中如何使用JSON字典類型解碼屬性

慕容708150 2019-12-17 14:35:58
假設我的Customer數據類型包含一個metadata屬性,該屬性可以在客戶對象中包含任何JSON字典struct Customer {  let id: String  let email: String  let metadata: [String: Any]}{    "object": "customer",  "id": "4yq6txdpfadhbaqnwp3",  "email": "[email protected]",  "metadata": {    "link_id": "linked-id",    "buy_count": 4  }}該metadata屬性可以是任意JSON映射對象。在我可以從反序列化的JSON強制轉換屬性(NSJSONDeserialization但使用新的Swift 4 Decodable協議)之前,我仍然想不出一種方法。有誰知道如何在Swift 4中使用Decodable協議實現這一目標?
查看完整描述

3 回答

?
慕哥6287543

TA貢獻1831條經驗 獲得超10個贊

我提出了一個略有不同的解決方案。


假設我們有比簡單[String: Any]解析還要多的東西:Any可能是數組,嵌套字典或數組字典。


像這樣:


var json = """

{

  "id": 12345,

  "name": "Giuseppe",

  "last_name": "Lanza",

  "age": 31,

  "happy": true,

  "rate": 1.5,

  "classes": ["maths", "phisics"],

  "dogs": [

    {

      "name": "Gala",

      "age": 1

    }, {

      "name": "Aria",

      "age": 3

    }

  ]

}

"""

好吧,這是我的解決方案:


public struct AnyDecodable: Decodable {

  public var value: Any


  private struct CodingKeys: CodingKey {

    var stringValue: String

    var intValue: Int?

    init?(intValue: Int) {

      self.stringValue = "\(intValue)"

      self.intValue = intValue

    }

    init?(stringValue: String) { self.stringValue = stringValue }

  }


  public init(from decoder: Decoder) throws {

    if let container = try? decoder.container(keyedBy: CodingKeys.self) {

      var result = [String: Any]()

      try container.allKeys.forEach { (key) throws in

        result[key.stringValue] = try container.decode(AnyDecodable.self, forKey: key).value

      }

      value = result

    } else if var container = try? decoder.unkeyedContainer() {

      var result = [Any]()

      while !container.isAtEnd {

        result.append(try container.decode(AnyDecodable.self).value)

      }

      value = result

    } else if let container = try? decoder.singleValueContainer() {

      if let intVal = try? container.decode(Int.self) {

        value = intVal

      } else if let doubleVal = try? container.decode(Double.self) {

        value = doubleVal

      } else if let boolVal = try? container.decode(Bool.self) {

        value = boolVal

      } else if let stringVal = try? container.decode(String.self) {

        value = stringVal

      } else {

        throw DecodingError.dataCorruptedError(in: container, debugDescription: "the container contains nothing serialisable")

      }

    } else {

      throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Could not serialise"))

    }

  }

}

嘗試使用


let stud = try! JSONDecoder().decode(AnyDecodable.self, from: jsonData).value as! [String: Any]

print(stud)


查看完整回答
反對 回復 2019-12-17
  • 3 回答
  • 0 關注
  • 750 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號