首页 > 解决方案 > Swift 4 枚举可编码

问题描述

我从 api 解析 json 数据。我的结构如下所示:

struct ServiceUnit: Codable {
        let description,id: String?
        let group, groupDescription:String?
        let name: String?
        var value: MyValue?

        enum CodingKeys: String, CodingKey {
            case description = "Description"
            case group = "Group"
            case groupDescription = "GroupDescription"
            case id = "Id"
            case name = "Name"
            case value = "Value"
        }
    }

    enum MyValue: Codable {
        case string(String)
        case innerItem(InnerItem)

        init(from decoder: Decoder) throws {
            let container = try decoder.singleValueContainer()
            if let string = try? container.decode(String.self) {
                self = .string(string)
                return
            }
            if let innerItem = try? container.decode(InnerItem.self) {
                self = .innerItem(innerItem)
                return
            }
            throw DecodingError.typeMismatch(MyValue.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for MyValue"))
        }

        func encode(to encoder: Encoder) throws {
            var container = encoder.singleValueContainer()
            switch self {
            case .string(let x):
                try container.encode(x)
            case .innerItem(let x):
                try container.encode(x)
            }
        }
    }

    struct InnerItem: Codable {
        let type, id, name: String

        enum CodingKeys: String, CodingKey {
            case type = "__type"
            case id = "Id"
            case name = "Name"
        }
    }

json数据如下所示:

    [
  {
  "Description": null,
  "Group": "Beskrivning av enheten",
  "GroupDescription": null,
  "Id": "Description",
  "Name": "Mer om enheten",
  "Value": "Det finns möjlighet till parkering på gatorna runt om, men det är kantstenar och ganska branta backar för att komma upp till lekplatsen.\r\n\r\nUtanför själva lekplatsen finns en gungställning med en plan omväg in. Alla lekredskap står i sandytor, det finns många kanter. Runt hela lekplatsen går ett staket med öppningar i olika riktningar."
  },
  {
  "Description": null,
  "Group": "Bilder och film",
  "GroupDescription": null,
  "Id": "Image",
  "Name": "Huvudbild",
  "Value": {
      "__type": "FileInfo",
      "Id": "8871b3b1-14f4-4054-8728-636d9da21ace",
      "Name": "ullerudsbacken.jpg"
  }
  }
  ]

加载数据后,我对其进行过滤以仅获取 id = description 的结果,然后重试 value 的值,如下所示:

let su = serviceUnit.filter{$0.id == "ShortDescription"}
            let description = su[0].value

然后,我的问题是,当我想使用该值填充标签时,我从 Xcode 收到此错误:

无法将类型的值分配MyValue?给类型String?

如果我打印su,我会得到这个:

[stockholmsParks.(0x105c3d098 处的未知上下文).ServiceUnit(描述:无,id:可选(“ShortDescription”),组:可选(“Beskrivning av enheten”),groupDescription:无,名称:可选(“Introduktion”),值:可选(斯德哥尔摩公园。(0x105c3d0e8 处的未知上下文).MyValue.string(“Regnbågen på höjden. Den här lekplatsen ligger på ett högt berg in naturmark, omgiven av höghus. Det finns en instängslad bollplan och olika lekredskap står placerade after varandra. Utanf själva lekplatsen finns en gungställning。Det finns också bänkbord i sol och grillplats。")))]

我错过了什么???

标签: iosswiftenumscodable

解决方案


您需要从枚举中获取相关值。

let value = su[0].value
switch value {
    case .string(let description)?:
        yourLabel.text = description
    default:
        break
}

推荐阅读