Ios Swift 4枚举可编码

Ios Swift 4枚举可编码,ios,swift,enums,codable,Ios,Swift,Enums,Codable,我从api解析json数据。我的结构如下所示: struct ServiceUnit: Codable { let description,id: String? let group, groupDescription:String? let name: String? var value: MyValue? enum CodingKeys: String, CodingKey { case

我从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"
        }
    }
    [
  {
  "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"
  }
  }
  ]
let su = serviceUnit.filter{$0.id == "ShortDescription"}
            let description = su[0].value
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"
        }
    }
    [
  {
  "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"
  }
  }
  ]
let su = serviceUnit.filter{$0.id == "ShortDescription"}
            let description = su[0].value
加载数据时,我对其进行过滤以仅获得id=description的结果,然后重试value的值,如下所示:

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"
        }
    }
    [
  {
  "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"
  }
  }
  ]
let su = serviceUnit.filter{$0.id == "ShortDescription"}
            let description = su[0].value
然后,我的问题是,当我想使用该值填充标签时,我从Xcode得到了这个错误:

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

如果我打印
su
,我会得到以下结果:

[stockholmsParks.(0x105c3d098处的未知上下文)。ServiceUnit(描述:nil,id:可选(“ShortDescription”)、组:可选(“Beskrivning av enheten”)、组描述:nil,名称:可选(“Introduction”)、值:可选(stockholmsParks.(0x105c3d0e8处的未知上下文)。MyValue.string(“Regnbågen påhöjden.Den hår lekplatsen ligger påett högt berg i naturmark,Omguid av höghus.Det finns en en instångslad bollplan och olika lekredskap ståplacerade efter varandra.Utanför själva lekplatsen finns en en en en gungställning.Det Finnocksåbåbäbord i sol Platoch。”)]


我缺少什么?

您需要从枚举中获取关联的值

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

您需要从枚举中获取关联的值

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

您正在尝试将
MyValue
的值设置为
String
变量。这就是您缺少的。枚举不会将自身强制转换为其他类型,您必须从
.String(String)中获取
String
参数
先处理大小写。此外,问题与
可编码的
无关,因为您的
解码
/
编码
代码很好。您正在尝试将
MyValue
的值设置为
String
变量。这就是您缺少的。Enum不会将自身强制转换为其他类型,您必须获得
String
参数超出
字符串(字符串)
case first。此外,问题与
Codable
无关,因为您的
解码
/
编码
代码很好。我之前确实尝试过,但我得到了以下错误:在类型“MyValue”中找不到枚举case“string”@user9865814检查我的更新答案,我实际上忘记了变量的可选性之前尝试过,我得到了以下错误:在类型“MyValue”中找不到枚举大小写“string”@user9865814检查我的更新答案,我忘记了变量的可选性