Hızlı Çözülebilir - genel türden nasıl kaçınılır?
JSON REST API'mden karmaşık bir iç içe geçmiş nesne alıyorum.
DocumentDraft
- uuid: String
- schema: Schema // Very complicated object with many variations
- url: String
- values: [Value]
- successors: [String]
- predecessors: [String]
Value
- key: String
- val: String? OR [String]? // <-- This is the problem
Sanırım bununla başa çıkmanın doğru yolu, genel bir tür tanıtmaktır.
struct Value<V: Decodable>: Decodable {
let key: String
let val: V?
}
... ama öyle bile olsa, values
karışık bir dizi olabilir, bu yüzden neyin işe V
yarayacağını bildirmenin nasıl yardımcı olacağını anlamıyorum .
Ama sonra, tabii ki jenerik tür, hiyerarşinin sonuna kadar, DocumentDraft
nesneye, yayıncıya, API çağrılarıma vs. yayılır , aksi takdirde çok temiz ve okunabilir çağrılar ve nesneler zincirinin tamamını kirletir. Bununla yalnızca düzeyinde ilgilenmek Value
ve JSONDecoder'ın bir şekilde ikisinden birini döndürmesine izin vermek istiyorum.
Üst nesnenin tamamını değiştirmeden val
ya String
da [String]
değiştirmeden isteğe bağlı olanın iki olasılığını ele almanın başka bir yolu var mı ?
Yanıtlar
Bunu yalnızca [String]
türü kullanarak ve aşağıdaki gibi protokol init(from:)
işlevini manuel olarak uygulayarak elde edebilirsiniz Decodable
:
struct Value: Decodable {
let key: String
let val: [String]?
enum CodingKeys: String, CodingKey {
case key, val
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
key = try container.decode(String.self, forKey: .key)
do {
if let string = try container.decodeIfPresent(String.self, forKey: .val) {
val = [string]
} else {
val = nil
}
} catch DecodingError.typeMismatch {
val = try container.decodeIfPresent([String].self, forKey: .val)
}
}
}
Değere kod çözme işlemi String
başarılı olduğunda, yalnızca bir öğe içeren bir dizi dizisi oluşturun. String
Değerin kodunu çözme başarısız olduğunda,[String]