Show single API response object per table cell when navigating through nested data

I’m working with a nested JSON API response and trying to display one question at a time in my table view. Right now I can navigate through the first level of nested data but I’m stuck when trying to move to the next question in the sequence.

Currently I’m at this question:

{
  "choice": 1234,
  "assessment": 100,
  "id": 501,
  "title": "What's your favorite pizza topping?",
  "choices": [],
  "description": "",
  "type": "rating",
  "creator": 3
}

But I need to navigate to the next question like this:

{
  "choice": null,
  "assessment": 100,
  "id": 502,
  "title": "Tell us about your weekend plans",
  "choices": [],
  "description": "",
  "type": "free_text",
  "creator": 3
}

Here’s my current implementation:

func traverseNestedData(_ questions: [SurveyQuestion]?) -> [Int: QuestionItem] {
    guard let questions = questions else {
        return [:]
    }
    
    var resultDict: [Int: QuestionItem] = [:]
    
    for question in questions {
        let questionItem = QuestionItem(id: question.id,
                                      title: question.title,
                                      description: question.description,
                                      type: question.type,
                                      assessment: question.assessment,
                                      options: convertOptions(question.options),
                                      choice: question.choice,
                                      creator: question.creator)
        resultDict[question.id] = questionItem
        if let options = question.options {
            for option in options {
                let nestedData = traverseNestedData(option.subQuestions)
                nestedData.forEach { (key, value) in
                    resultDict[key] = value
                }
            }
        }
    }
    questionDict = resultDict
    return resultDict
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return surveyData.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "SurveyCell", for: indexPath) as? SurveyTableCell else { return UITableViewCell() }
    
    cell.questionLabel.text = surveyData[indexPath.row].options?[indexPath.row].title
    
    return cell
}

struct SurveyQuestion: Codable {
    let id: Int
    let title, description, type: String
    let assessment: Int
    let options: [QuestionOption]?
    let choice: Int?
    let creator: Int
}

struct QuestionOption: Codable {
    let id: Int
    let title: String
    let category: String
    let question: Int
    let subQuestions: [SurveyQuestion]?
}

The problem is my code isn’t properly navigating through the nested structure. How can I modify this to show one question at a time and move between them correctly?

Your traverseNestedData function looks fine for flattening, but there’s a problem in cellForRowAt. You’re doing surveyData[indexPath.row].options?[indexPath.row].title which double-indexes and ignores your questionDict completely. Here’s what I’d do instead: create an array of question IDs in sequence order when you parse. Like var questionSequence: [Int] = [] that gets filled during traversal. Then in cellForRowAt, just use let questionId = questionSequence[indexPath.row] and let question = questionDict[questionId]. You’ll keep the right order but still get fast lookups for individual questions.

you’re mixing up navigation with data parsing. set up a currentQuestionIndex variable to track which question you’re showing, then use that index to grab the right question from your flattened questionDict. try cell.questionLabel.text = Array(questionDict.values)[currentQuestionIndex].title instead of using indexPath for both the array and nested options.

The problem is you’re building a dictionary but not handling sequential navigation properly. You need to keep track of the question order as it appears in your nested structure.

Here’s what I’d do: when you call traverseNestedData, also build a questionOrder: [Int] array that saves the sequence. Then in your table view methods, use numberOfRowsInSection to return questionOrder.count. In cellForRowAt, grab the question like this: let questionId = questionOrder[indexPath.row] then let question = questionDict[questionId].

This gives you the best of both worlds - you keep the sequential order for navigation but still get fast dictionary lookups.