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



问题:我正在尝试解码我的JSON,其中一些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?
}

这是德米特里·谢罗夫帮助我使用的示例单元格。

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 {
....
}
}

这是德米特里·谢罗夫帮助我的更多代码。

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 {
}
}

这是我使用可编码解码的 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
}
}
}

最新更新