Извиняюсь за длинный вопрос.
Я использую Firestore для хранения онлайн-данных и имею текущую структуру, как показано ниже;
{
"activities": {
"mG47rRED9Ym4dkXinXrN": {
"createdAt": 1234567890,
"activityType": {
"title": "Some Title"
}
},
"BF3jhINa1qu9kia00BeG": {
"createdAt": 1234567890,
"activityType": {
"percentage": 50,
}
}
}
}
Я использую декодируемый протокол JSON для извлечения данных. У меня есть основная структура;
struct Activity: Decodable {
let documentID: String
let createdAt: Int
let activityType: ActivityType
}
эта структура содержит обязательные данные, такие как createdAt и documentID (т. е. «mG47rRED9Ym4dkXinXrN»). В зависимости от данных, вложенных в «activityType», он должен возвращать одну из двух структур, перечисленных ниже;
struct NewGoal: Decodable {
let title: String
}
struct GoalAchieved: Decodable {
let percentage: Double
}
Я делаю это с помощью декодируемого перечисления;
enum ActivityType: Decodable {
case newGoal(NewGoal)
case goalAchieved(GoalAchieved)
}
extension ActivityType {
private enum CodingKeys: String, CodingKey {
case activityType
}
init(from decoder: Decoder) throws {
let values = try? decoder.container(keyedBy: CodingKeys.self)
if let value = try? values?.decode(GoalAchieved.self, forKey: .activityType) {
self = .goalAchieved(value)
return
}
if let value = try? values?.decode(NewGoal.self, forKey: .activityType) {
self = .newGoal(value)
return
}
throw DecodingError.decoding("Cannot Decode Activity")
}
}
При использовании структуры Activity в качестве моего массива я получаю DecodingError. Однако при использовании ActivityType в качестве моего массива он будет нормально декодироваться, но не даст доступа к documentID и createdAt. Я не могу наследовать структуру Activity, поскольку она не является протоколом. Как мне структурировать это, пожалуйста?