2017-09-09 53 views
1

我有一個Swift應用程序,我正在轉換使用Codable協議(而不是EVReflection,它改變了很多,我可以不再使它工作)。當與應用程序服務器進行交易時,我的代碼會生成一個類「ServerResponse」的對象,其中包含許多變量 - 其中一個是「responseObject」 - 可以是任意數量的不同對象,從用戶到消息,或其他。因爲默認情況下Codable不使用「decodeIfPresent」,所以在某些事務中我得到錯誤,並且必須覆蓋init(來自解碼器:Decoder)以防止出現這種情況。現在我面臨的挑戰是如何將原始JSON字符串完整保留,以便稍後通過調用方法解碼爲正確的對象類型或其他類似的修復。底線:我需要responseObject靈活並允許我的服務器選擇發送的任何類型的對象。Swift 4 - Codable - 如何允許在解碼時允許不同對象類型的鍵

如果有人有任何建議,我將不勝感激。如果能夠提供幫助,我很樂意分享代碼,但我不認爲這會是因爲這個問題本質上是概念性的。

+0

嘗試解碼可能是幾種類型之一的一般解決方案是嘗試將其解碼爲一種類型,如果由於類型不匹配而失敗,請嘗試下一種類型。像這樣的'responseObject',還是一個完全不受約束的類型?你能舉一個JSON有效負載看起來像什麼的具體例子嗎? –

+0

它不完全沒有受到任何限制,但是在我的應用程序中有34種不同的對象可以通過。我真的很喜歡將原始的JSON完全保留,所以我可以從調用方法手動解碼它。有沒有辦法做到這一點? – Joel

+1

目前還沒有,沒有。這是目前正在考慮的功能。 –

回答

2

你可以做類似的措施: -

struct CustomAttribute: Codable { 
var attributeCode: String? 
var intValue: Int? 
var stringValue: String? 
var stringArrayValue: [String]? 

enum CodingKeys: String, CodingKey { 

    case attributeCode = "attribute_code" 
    case intValue = "value" 
    case stringValue 
    case stringArrayValue 
} 

init(from decoder: Decoder) throws { 
    let values = try decoder.container(keyedBy: CodingKeys.self) 

    attributeCode = try values.decode(String.self, forKey: .attributeCode) 
    if let string = try? values.decode(String.self, forKey: .intValue) { 
     stringValue = string 
    } else if let int = try? values.decode(Int.self, forKey: .intValue) { 
     intValue = int 
    } else if let intArray = try? values.decode([String].self, forKey: .intValue) { 
     stringArrayValue = intArray 
    } 
} 

} 

這裏的值可以是三種類型的和我手動確定哪些類型是。