erikvm
erikvm

Reputation: 928

Update and append decoded JSON into struct?

I'm receiving some paginated JSON response through my API that looks something like this:

page 1:

{
    "count": 96,
    "next": "http://127.0.0.1:8000/id=5/?page=2",
    "previous": null,
    "results": [
        {
            "id": 10,
            "book_name": "Book name",
            "book_id": 70,
            "chapter_number": 1,
            "verse": "Verse title here",
            "verse_number": 1,
            "chapter": 96
        },
        {
            "id": 198,
            "book_name": "Book Name",
            "book_id": 70,
            "chapter_number": 8,
            "verse": "Text here",
            "verse_number": 5,
            "chapter": 103
        }
    ]
}

As I move through the paginated result, ie calling: http://127.0.0.1:8000/id=5/?page=2 I'll get new values in the results array.

page 2:

{
    "count": 96,
    "next": "http://127.0.0.1:8000/id=5/?page=3",
    "previous": "http://127.0.0.1:8000/id=5/",
    "results": [
        {
            "id": 206,
            "book_name": "Book on Second page",
            "book_id": 70,
            "chapter_number": 8,
            "verse": "yadda yadda",
            "verse_number": 13,
            "chapter": 103
        },
        {
            "id": 382,
            "book_name": "Book on second page..",
            "book_id": 70,
            "chapter_number": 15,
            "verse": "Verse here",
            "verse_number": 12,
            "chapter": 110
        }
    ]
}

How would I structure my struct/fix my decoding so I can append the values of results from the JSON while still updating count, next and previous as I go through ..?page=3, ..?page=4 etc

Currently, my struct looks like this:

struct VersesSearchResult: Decodable {
    var results: [Verse]
    var count: Int
    var next: String?
    var previous: String?
}

When doing the decoding, I'm not sure what the syntax should be like to append results to the struct, and update next, previous, and count. So far I got this

...
let verses = try JSONDecoder().decode(VersesSearchResult, from: safeData)
DispatchQueue.main.async {
    // somehow need to get this to work - not entirely sure how
    // where results gets appended, while the rest in the JSON values gets updated
   // obviously I can't do as below:
    self.verseSearchResult.append(contentsOf: verses.results)
    self.verseSearchResult = verses
}
...

Upvotes: 0

Views: 569

Answers (1)

flanker
flanker

Reputation: 4200

Decode to a temprary instance of the type, then process those properties into your main instance. Depending how you want to process the data, it'll look something like this

extension VersesSearchResult {

  mutating func update(with new: VersesSearchResult) {
    results.append(new)
    count = new.count
    next = new.next
    prev = new.prev
  }
}

and then in your completion block

let newVerses = try JSONDecoder().decode(VersesSearchResult, from: safeData)
self.verses.update(with: newVerses)

If needs be force the update onto the main thread.

You should also handle failure in the 'try' either with a do...catch or other approach.

Upvotes: 0

Related Questions