0

How can I decode the following using swift Decodable? I'm only interested in the extract value

{  
   "batchcomplete":"",
   "query":{  
      "normalized":[  ],
      "pages":{  
         "434325":{    //can be any number!
            "pageid":434325,
            "ns":0,
            "title":"asdfasdfsa",
            "extract":""

I'm attempting the following:

struct Entry: Decodable {
    let batchcomplete: String
    let query: Query

    struct Query: Decodable {
        let normalized: [String]
        let pages: Page

        struct Page: Decodable {
            let pageid: Entry // I think this is going to be an issue

            struct Entry: Decodable {
                let title: String
                let extract: String 
            }

        }
    }
}

I'm trying to retrieve the extract like this:

  print(entry.query.pages.first.extract) 

Is there a way to use .first for this ?

I'm only every going to get maximum one page so ideally I would just grab the first element.

Ayrad
  • 3,996
  • 8
  • 45
  • 86
  • 1
    Decoding JSON using Generics [Hope this helps](https://stackoverflow.com/questions/53367491/decode-json-string-to-class-object-swift/53367705#53367705) – prex Feb 01 '19 at 08:10
  • If you just need one value, SwiftyJSON might be easier to use. – Sweeper Feb 01 '19 at 08:11
  • this can help https://stackoverflow.com/questions/53268833/swift-4-decodable-with-unknown-dynamic-keys – Suhit Patil Feb 01 '19 at 08:16
  • Possible duplicate of [Swift 4 Decodable with keys not known until decoding time](https://stackoverflow.com/questions/45598461/swift-4-decodable-with-keys-not-known-until-decoding-time) – EJoshuaS - Stand with Ukraine Feb 02 '19 at 00:10

1 Answers1

1

Your decoding code is ok up until `Query type.

So what should be used instead:

struct Query: Decodable {
    let normalized: [String]
    let pages: [String: Page]

    struct Page: Decodable {
        let pageid: Int
        let title: String
        let extract: String
    }
}

So, key points:

  1. If you don't know what keys would be there, use [String: <SomeDecodableType>] because any JSON Object can be mapped to the [String: <Decodable>].
  2. You don't need to declare Page.Entry, just put all the fields to the Page
  3. To get extract instead of entry.query.pages.first.extract you will have to use entry.query.pages.first?.value.extract (extract of first random page, because [String: Page] is unsorted) or entry.query.pages.sorted(by: sorter).first?.value.extract (where sorter is some function, that takes two key-value pairs and returns true if first one should go before second one in order) to get first using some order.
user28434'mstep
  • 6,290
  • 2
  • 20
  • 35