0

我有一个可编码的对象,如下所示:

struct IncidentResponse: Codable {
    let incident: IncidentDetails?
}

struct IncidentDetails: Codable, Identifiable {
    let id: String?
    let reason: IncidentReasonResponse?
    let message: String?
    let startedAt: String?
    let endedAt: String?
}

struct IncidentReasonResponse: Codable, Identifiable {
    let id: String?
    let name: String?
    let code: String?
    let inOp: Bool?
}

以下是从 API 调用时的事件响应示例:

{
  "incident": {
    "id": "610aebad8c719475517e9736",
    "user": null,
    "reason": {
      "name": "No aircraft",
      "code": "no-aircraft",
      "inOp": true
    },
    "message": "test this",
    "startedAt": "2021-08-04T19:34:05+0000",
    "endedAt": null
  }
}

在 SwiftUI 中,我试图显示这些列表。所以我有一个名为existingIncidents的这些IncidentResponse对象的数组,然后是以下内容:

var body: some View {
    List {
        Section(header: Text("Existing incidents")) {
            if let existingIncidents = self.existingIncidents {
                ForEach(existingIncidents) { incident in
                    
                    VStack(alignment: .leading) {
                        HStack {
                            Image.General.incident
                                .foregroundColor(Constants.iconColor)
                            Text(incident.incident?.reason?.name ?? "")
                                .foregroundColor(Constants.textColor)
                                .bold()
                        }
                        Spacer()
                        HStack {
                            Image.General.clock
                                .foregroundColor(Constants.iconColor)
                            Text(incident.incident?.startedAt ?? "No date")
                                .foregroundColor(Constants.textColor)
                        }
                        Spacer()
                        HStack {
                            Image.General.message
                                .foregroundColor(Constants.iconColor)
                            Text(incident.incident?.message ?? "No message")
                                .foregroundColor(Constants.textColor)
                        }
                    }
                }
            }
        }
    }
    .listStyle(PlainListStyle())

但是,我无法使用现有事件,因为它不符合 Identifiable 或 Hashable(所以我不能使用 id: /.self 解决方法)...

我怎样才能解决这个问题?

我尝试将 UUID 添加到 IncidentResponse 中,如下所示:

struct IncidentResponse: Codable {
    let incident: IncidentDetails?
    var id = UUID().uuidString
}

但是,这会阻止对象从 API 正确解码。

4

1 回答 1

3

选项1:

给您IncidentResponse一个 ID,然后告诉它不要尝试解码该值:

struct IncidentResponse: Codable, Identifiable {
    var id = UUID()
    let incident: IncidentDetails?
    
    enum CodingKeys: String, CodingKey {
        case incident
    }
}

选项 2:

Makeincidentidnon-optional 然后使用它来获取 id:

ForEach(existingIncidents, id: \.incident.id) { incident in

我还要注意,此时这IncidentResponse似乎是一个毫无意义的包装。当您进行解码并将值存储到existingIncidents(您尚未显示)时,您可能可以将它们存储起来[IncidentDetails]。在这种情况下,您只需将id属性设为非可选 onIncidentDetails并将其声明为Identifiable. 例如:

struct IncidentDetails: Codable, Identifiable {
    let id: String
    let reason: IncidentReasonResponse?
    let message: String?
    let startedAt: String?
    let endedAt: String?
}

//....

let existingIncidentsWrappers : [IncidentResponse] = //...
let existingIncidents : [IncidentDetails] = existingIncidentsWrappers.compactMap { $0.incident }
于 2021-09-28T21:14:05.377 回答