2017-10-14 60 views
1

(這是這個問題的後續:Using Decodable protocol with multiples keys雨燕可解碼可選關鍵

我有以下的銀行代碼:

let additionalInfo = try values.nestedContainer(keyedBy: UserInfoKeys.self, forKey: .age) 
age = try additionalInfo.decodeIfPresent(Int.self, forKey: .realage) 

我知道,如果我使用decodeIfPresent和唐如果它是一個可選變量,它將不會正確處理它。

例如,以下JSON使用上面的代碼解析它。

{ 
    "firstname": "Test", 
    "lastname": "User", 
    "age": {"realage": 29} 
} 

而下面的JSON也適用。

{ 
    "firstname": "Test", 
    "lastname": "User", 
    "age": {"notrealage": 30} 
} 

但是,以下不起作用。

{ 
    "firstname": "Test", 
    "lastname": "User" 
} 

如何讓所有3個示例都可以工作? nestedContainer有沒有類似於decodeIfPresent

回答

8

您可以使用以下KeyedDecodingContainer功能:

func contains(_ key: KeyedDecodingContainer.Key) -> Bool 

返回Bool值,指示解碼器是否包含與給定鍵關聯的值。與給定鍵相關聯的值可以是適合數據格式的空值。

檢查是否"age"鍵存在之前請求相應的嵌套容器。例如:

struct Person: Decodable { 
    let firstName, lastName: String 
    let age: Int? 

    enum CodingKeys: String, CodingKey { 
     case firstName = "firstname" 
     case lastName = "lastname" 
     case age 
    } 

    enum AgeKeys: String, CodingKey { 
     case realAge = "realage" 
     case fakeAge = "fakeage" 
    } 

    init(from decoder: Decoder) throws { 
     let values = try decoder.container(keyedBy: CodingKeys.self) 
     self.firstName = try values.decode(String.self, forKey: .firstName) 
     self.lastName = try values.decode(String.self, forKey: .lastName) 

     if values.contains(.age) { 
      let age = try values.nestedContainer(keyedBy: AgeKeys.self, forKey: .age) 
      self.age = try age.decodeIfPresent(Int.self, forKey: .realAge) 
     } else { 
      self.age = nil 
     } 
    } 
} 
0

您可以嘗試將您的示例JSON粘貼到quicktype以查看它推斷的類型?根據你的問題,我貼你的樣品,並得到:

struct UserInfo: Codable { 
    let firstname: String 
    let age: Age? 
    let lastname: String 
} 

struct Age: Codable { 
    let realage: Int? 
} 

製作UserInfo.ageAge.realage自選作品,如果這是你要完成什麼。

+1

我試圖用1類/結構實現這一點。我有1個類/結構設計它的具體原因。有關詳細信息,請參閱我的問題和答案[此處](https://stackoverflow.com/a/46737735/894067)。 –

+0

啊,我明白了 - 我必須同意那裏的答案,這個答案提出了一個與JSON結構相對應的「原始」模型,您可以用您希望的特質行爲映射到您的更高層模型!我認爲這比實現定製解碼器更容易維護和理解,但祝你好運! –

+0

就像我的數據在我的服務器文件中的結構一樣,這使得使用自定義解碼器更容易。而從我的理解和結構來看,以這種方式做起來要容易得多。也許有人能夠給出符合我想要的答案。謝謝你的幫助。 –