Last active
          March 3, 2022 00:57 
        
      - 
      
 - 
        
Save IanKeen/4403dba9253b7da165e3586c80a052b8 to your computer and use it in GitHub Desktop.  
    Skipping nested wrappers in json w/ Codable
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | extension KeyedDecodingContainer { | |
| func decode<T: Decodable, Inner: CodingKey>(_ type: T.Type, forKey key: KeyedDecodingContainer.Key, innerKey: Inner) throws -> [T] { | |
| var array = try nestedUnkeyedContainer(forKey: key) | |
| var items: [T] = [] | |
| while !array.isAtEnd { | |
| let container = try array.nestedContainer(keyedBy: Inner.self) | |
| let item = try container.decode(T.self, forKey: innerKey) | |
| items.append(item) | |
| } | |
| return items | |
| } | |
| func decodeIfPresent<T: Decodable, Inner: CodingKey>(_ type: T.Type, forKey key: KeyedDecodingContainer.Key, innerKey: Inner) throws -> [T]? { | |
| guard contains(key) else { return nil } | |
| return try decode(type, forKey: key, innerKey: innerKey) | |
| } | |
| } | |
| extension KeyedEncodingContainer { | |
| mutating func encode<T: Encodable, Inner: CodingKey>(_ value: [T], forKey key: KeyedEncodingContainer.Key, innerKey: Inner) throws { | |
| var array = nestedUnkeyedContainer(forKey: key) | |
| for item in value { | |
| var container = array.nestedContainer(keyedBy: Inner.self) | |
| try container.encode(item, forKey: innerKey) | |
| } | |
| } | |
| mutating func encodeIfPresent<T: Encodable, Inner: CodingKey>(_ value: [T]?, forKey key: KeyedEncodingContainer.Key, innerKey: Inner) throws { | |
| guard let value = value, !value.isEmpty else { return } | |
| try encode(value, forKey: key, innerKey: innerKey) | |
| } | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | struct Parent: Codable { | |
| let items: [Item] | |
| } | |
| struct Item: Codable { | |
| let name: String | |
| } | |
| extension Parent { | |
| private enum CodingKeys: String, CodingKey { | |
| case attachments | |
| } | |
| private enum AttachmentKeys: String, CodingKey { | |
| case content | |
| } | |
| init(from decoder: Decoder) throws { | |
| let container = try decoder.container(keyedBy: CodingKeys.self) | |
| self.items = try container.decode(Item.self, forKey: .attachments, innerKey: AttachmentKeys.content) | |
| } | |
| func encode(to encoder: Encoder) throws { | |
| var container = encoder.container(keyedBy: CodingKeys.self) | |
| try container.encode(items, forKey: .attachments, innerKey: AttachmentKeys.content) | |
| } | |
| } | |
| let json = """ | |
| { | |
| "attachments": [ | |
| { | |
| "content": { | |
| "name": "foo" | |
| } | |
| }, | |
| { | |
| "content": { | |
| "name": "bar" | |
| } | |
| } | |
| ] | |
| } | |
| """.data(using: .utf8)! | |
| do { | |
| let object = try JSONDecoder().decode(Parent.self, from: json) | |
| print(object.items) | |
| let parent = Parent(items: [ | |
| Item(name: "foo"), | |
| Item(name: "bar") | |
| ] | |
| ) | |
| print(try String(data: JSONEncoder().encode(parent), encoding: .utf8)!) | |
| } catch let error { | |
| print(error) | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment