Search code examples
jsonswiftapicodabledecodable

Extracting only some fields from a JSON with Swift


I am sorry, but I am new to Swift programming. I am using NewsAPI in my app. Their responses are formatted like this:

{
  "status": "ok",
  "totalResults": 38,
  "articles": [
    {
      "source": {
        "id": "cnn",
        "name": "CNN"
      },
      "author": "Eric Levenson and Lauren del Valle, CNN",
      "title": "Actress Annabella Sciorra is in court at Harvey Weinstein's trial for potential testimony - CNN",
      "description": "Actress Annabella Sciorra is in court for Harvey Weinstein's criminal trial, setting up what could be the first face-to-face testimony from one of the women who has accused him of sexual assault.",
      "url": "https://www.cnn.com/2020/01/23/us/harvey-weinstein-annabella-sciorra/index.html",
      "urlToImage": "https://cdn.cnn.com/cnnnext/dam/assets/200123090608-annabella-sciorra-file-super-tease.jpg",
      "publishedAt": "2020-01-23T16:22:00Z",
      "content": "New York (CNN)Actress Annabella Sciorra is in court for Harvey Weinstein's criminal trial, setting up what could be the first face-to-face testimony from one of the women who has accused him of sexual assault.\r\n\"The Sopranos\" actress has said Weinstein raped … [+5398 chars]"
    },
    {
      "source": {
        "id": "ars-technica",
        "name": "Ars Technica"
      },
      "author": "Jennifer Ouellette",
      "title": "Jewel beetle’s bright colored shell serves as camouflage from predators - Ars Technica",
      "description": "University of Bristol scientists offer first real evidence for a 100-year-old theory.",
      "url": "https://arstechnica.com/science/2020/01/study-jewel-beetles-use-iridescence-for-camouflage-not-sexual-selection/",
      "urlToImage": "https://cdn.arstechnica.net/wp-content/uploads/2020/01/beetleTOP-760x380.jpg",
      "publishedAt": "2020-01-23T16:00:00Z",
      "content": "Enlarge/ The brightly colored shell of this jewel beetle is a surprisingly effective form of camouflage, according to a new study by scientists at the University of Bristol.\r\n23 with 20 posters participating\r\nArtist and naturalist Abbott Handerson Thayer beca… [+5422 chars]"
    }]
}

I have a way of using this data, but it involves too many unnecessary structs/classes. Is there a way for me to decode only the articles array from the response into a struct Article defined like this:

struct Article: Decodable {
    let author: String?
    let title: String?
    let description: String?
    let url: String?
    let urlToImage: String?
    let publishedAt: String?
}

Thank you for your time :)


Solution

  • Yes you can grab only the part you are interested in.

    1. Define your model

    When defining your model you can declare only the fields you are interested in.

    Since in a comment below you said you only want author and title for each Article I updated the Article struct accordingly.

    struct Response: Decodable {
    
        let articles: [Article]
    
        struct Article: Decodable {
            let author: String
            let title: String
        }
    }
    

    2. Decode

    do {
        let response = try JSONDecoder().decode(Response.self, from: data)
        let articles = response.articles
        print(articles)
    } catch {
        print(error)
    }