0

So this is the response structure that I have.

The same identifier attribute, can have a data associated with it that can be a list of other objects. The outermost table is list of other view types and the inner table is list of rows, if that makes sense.

{
  "identifier": "table",
  "data": [
    {
      "identifier": "top_view",
      "data": [
        {
          "value": "this is top header type view"
        }
      ]
    },
    {
      "identifier": "table",
      "data": [
        {
          "value": "this is a first row in a table"
        },
        {
          "value": "this is a second row in a table"
        },
        {
          "value": "this is a third row in a table"
        }
      ]
    },
    {
      "identifier": "bottom_view",
      "data": [
        {
          "value": "this is a footer type view"
        }
      ]
    }
  ]
}

Can I use swifts Codable to decode this in anyway? Solutions for this type of decoding generally involve having an enum around differentdata and using this to inject the correct type associated with it. But in this case, the identifier is the same.

Let me know if I need to add in more details.

Edit 1 - Well, I am trying to build a new app that has a backend driven UI. This is just the response of a screen within the app. 
To explain more about the json - The outermost table is a tableview that can have 3 cells - the first one being the top header, second a table(that again has 3 cells that each consists of label) and the third is a bootom footer (Not to be confused with a tableviews default header footer).

I understand that the json might be flawed in itself but initially I had hoped that it would work by employing a nested json structure (hence the use of same data key) The value of data in this case can change across different components.

enter image description here

3
  • First make if your possible change the json, do so. It is poorly designed and shouldn't have different data types for the same key. If you can't change it then you will need to implement your own init(decoder) method Commented Mar 29, 2021 at 0:56
  • 1
    What model would you want to decode it into? Commented Mar 29, 2021 at 1:50
  • This is definitely possible to decode, but it would be helpful to show what Swift structs you'd like to end with. If you were going to encode the above data structure purely by writing Swift code (without any JSON), what would you most want it to look like? It's not very clear what this JSON represents. Commented Mar 29, 2021 at 2:11

1 Answer 1

2

I think I understand what you are trying to achieve (from what you were saying about the enum). This is something to get you started --

struct TableableData: Codable {
    
    enum ViewType {
        
        case top(values: [String])
        case bottom(values: [String])
        case table(data: [TableableData])
        
        init?(identifier: String?, data: [TableableData]) {
            switch identifier {
            case "top_view": self = .top(values: data.compactMap{ $0.value })
            case "bottom_view": self = .top(values: data.compactMap{ $0.value })
            case "table": self = .table(data: data)
            default: return nil
            }
        }
    }
    
    let identifier: String?
    let value: String?
    let data: [TableableData]!
    
    var view: ViewType? {
        ViewType(identifier: identifier, data: data)
    }
}

I had to make all fields optional to quickly test it against your json, it works. I would suggest using init from decoder to replace optional with empty array or something.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.