Search code examples
jsonswiftgoogle-custom-search

Decoding Google custom search API in Swift 4 using decodable protocol


Here is my json:

 "metatags": [
         {
          ....

          "og:url": "http://www.theguardian.com/world/2018/feb/27/ensuring-happier-lives-chinese-media-defends-move-to-make-xi-jinping-all-powerful",
          "article:author": "https://www.theguardian.com/profile/tomphillips",
          "og:image:height": "720",
          "og:description": "United States declines to criticise removal of term limits as liberal thinkers inside China say move deserves to be ‘mocked by civilised countries’",
          "og:image:width": "1200",
          "og:image": "https://i.guim.co.uk/img/media/5d33d9276cf4388564b5bf4d42e0cd4ad8ec221e/0_230_6835_4101/master/6835.jpg?w=1200&h=630&q=55&auto=format&usm=12&fit=crop&crop=faces%2Centropy&bm=normal&ba=bottom%2Cleft&blend64=aHR0cHM6Ly91cGxvYWRzLmd1aW0uY28udWsvMjAxOC8wMS8zMS9mYWNlYm9va19kZWZhdWx0LnBuZw&s=391c7c897cafc35a55dd29b48ed544d5",
          "al:ios:url": "gnmguardian://world/2018/feb/27/ensuring-happier-lives-chinese-media-defends-move-to-make-xi-jinping-all-powerful?contenttype=Article&source=applinks",
          "article:publisher": "https://www.facebook.com/theguardian",
          "og:type": "article",
          "al:ios:app_store_id": "409128287",
          "article:section": "World news",
          "article:published_time": "2018-02-27T03:36:30.000Z",
          "og:title": "'Ensuring happier lives': Chinese media defends move to make Xi Jinping all powerful",
          "fb:app_id": "180444840287",
          "article:tag": "China,Xi Jinping,Asia Pacific,World news",
          "al:ios:app_name": "The Guardian",
          "og:site_name": "the Guardian",
....
         }
        ]

It is a response of this API, I want to parse out image, title, description, and site name which are all present in the response. This is so far the data model I have created:

struct Metadata: Decodable{
    var metatags: [enclosedTags]

}
    struct enclosedTags: Decodable{
        let image: String
        let title: String
        let description: String
        let siteName: String

        private enum codingKeys : String, CodingKey{
            case image = "og:image", title = "og:title", description = "og:description", siteName = "og:site_name"
        }
    }

@IBAction func onSearch(_ sender: UIButton){

        let session = URLSession.shared


        let datatask = session.dataTask(with: request as URLRequest) { (data, response, error) in
            guard let data = data else {
                print ("Error: Handling URL request")
                return }
            do{
    let tags = try JSONDecoder().decode(Metadata.self, from: data)
                print(tags.metatags)
}
            catch let jerror{
                print("here", jerror)
 }
        }
        datatask.resume()
    }

Upon using this I get the following error: keyNotFound(Social_Login_api.Metadata.(CodingKeys in _7FFB0C3B2CCB4BCEDB9D03985979711B).metatags, Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key metatags (\"metatags\").", underlyingError: nil))

Am I declaring the struct wrong or is there an issue with handling the JSON request, any helpful insights would be great.

Edit-1: Here is the whole JSON response as requested,

{
 "kind": "customsearch#search",
 "url": {
  "type": "application/json",
  "template": "https://www.googleapis.com/customsearch/v1?q={searchTerms}&num={count?}&start={startIndex?}&lr={language?}&safe={safe?}&cx={cx?}&sort={sort?}&filter={filter?}&gl={gl?}&cr={cr?}&googlehost={googleHost?}&c2coff={disableCnTwTranslation?}&hq={hq?}&hl={hl?}&siteSearch={siteSearch?}&siteSearchFilter={siteSearchFilter?}&exactTerms={exactTerms?}&excludeTerms={excludeTerms?}&linkSite={linkSite?}&orTerms={orTerms?}&relatedSite={relatedSite?}&dateRestrict={dateRestrict?}&lowRange={lowRange?}&highRange={highRange?}&searchType={searchType}&fileType={fileType?}&rights={rights?}&imgSize={imgSize?}&imgType={imgType?}&imgColorType={imgColorType?}&imgDominantColor={imgDominantColor?}&alt=json"
 },
 "queries": {
  "request": [
   {
    "title": "Google Custom Search - 'Ensuring happier lives': Chinese media defends move to make Xi Jinping all powerful  United States declines to criticise removal of term limits as liberal  thinkers inside China say move deserves to be 'mocked by civilised countries'     ",
    "totalResults": "4",
    "searchTerms": "'Ensuring happier lives': Chinese media defends move to make Xi Jinping all powerful  United States declines to criticise removal of term limits as liberal  thinkers inside China say move deserves to be 'mocked by civilised countries'     ",
    "count": 4,
    "startIndex": 1,
    "inputEncoding": "utf8",
    "outputEncoding": "utf8",
    "safe": "off",
    "cx": "003086370729948886707:yvy2bcavdtu"
   }
  ]
 },
 "context": {
  "title": "*.google"
 },
 "searchInformation": {
  "searchTime": 0.633407,
  "formattedSearchTime": "0.63",
  "totalResults": "4",
  "formattedTotalResults": "4"
 },
 "items": [
  {
   "kind": "customsearch#result",
   "title": "'Ensuring happier lives': Chinese media defends move to make Xi ...",
   "htmlTitle": "'\u003cb\u003eEnsuring happier lives': Chinese media defends move\u003c/b\u003e to \u003cb\u003emake Xi\u003c/b\u003e ...",
   "link": "https://www.theguardian.com/world/2018/feb/27/ensuring-happier-lives-chinese-media-defends-move-to-make-xi-jinping-all-powerful",
   "displayLink": "www.theguardian.com",
   "snippet": "'Ensuring happier lives': Chinese media defends move to make Xi Jinping all \npowerful. United States declines to criticise removal of term limits as liberal \nthinkers inside China say move deserves to be 'mocked by civilised countries'. \nTom Phillips in Beijing. Mon 26 Feb 2018 22.36 EST Last modified on Mon 26 \nFeb 2018 ...",
   "htmlSnippet": "'\u003cb\u003eEnsuring happier lives': Chinese media defends move\u003c/b\u003e to \u003cb\u003emake Xi Jinping all\u003c/b\u003e \u003cbr\u003e\n\u003cb\u003epowerful\u003c/b\u003e. \u003cb\u003eUnited States declines\u003c/b\u003e to \u003cb\u003ecriticise removal\u003c/b\u003e of \u003cb\u003eterm limits\u003c/b\u003e as \u003cb\u003eliberal\u003c/b\u003e \u003cbr\u003e\n\u003cb\u003ethinkers inside China say move deserves\u003c/b\u003e to be '\u003cb\u003emocked\u003c/b\u003e by \u003cb\u003ecivilised countries\u003c/b\u003e'. \u003cbr\u003e\nTom Phillips \u003cb\u003ein\u003c/b\u003e Beijing. Mon 26 Feb 2018 22.36 EST Last modified on Mon 26 \u003cbr\u003e\nFeb 2018 ...",
   "cacheId": "x54qfhvXmSYJ",
   "formattedUrl": "https://www.theguardian.com/.../ensuring-happier-lives-chinese-media- defends-move-to-make-xi-jinping-all-powerful",
   "htmlFormattedUrl": "https://www.theguardian.com/.../\u003cb\u003eensuring\u003c/b\u003e-\u003cb\u003ehappier\u003c/b\u003e-\u003cb\u003elives\u003c/b\u003e-\u003cb\u003echinese\u003c/b\u003e-\u003cb\u003emedia\u003c/b\u003e- \u003cb\u003edefends\u003c/b\u003e-\u003cb\u003emove-to-make\u003c/b\u003e-\u003cb\u003exi\u003c/b\u003e-\u003cb\u003ejinping\u003c/b\u003e-\u003cb\u003eall\u003c/b\u003e-\u003cb\u003epowerful\u003c/b\u003e",
   "pagemap": {
    "thumbnail": [
     {
      "src": "https://i.guim.co.uk/img/media/5d33d9276cf4388564b5bf4d42e0cd4ad8ec221e/0_230_6835_4101/master/6835.jpg?w=620&q=55&auto=format&usm=12&fit=max&s=c857db05131da665271beb49d600180d"
     }
    ],
    "metatags": [
     {
      "format-detection": "telephone=no",
      "handheldfriendly": "True",
      "viewport": "width=device-width,minimum-scale=1,initial-scale=1",
      "apple-mobile-web-app-title": "Guardian",
      "application-name": "The Guardian",
      "msapplication-tilecolor": "#e7edef",
      "theme-color": "#e7edef",
      "msapplication-tileimage": "https://assets.guim.co.uk/images/favicons/77beb32f01ee0157ec193e09e4e18c4e/windows_tile_144_b.png",
      "apple-itunes-app": "app-id=409128287, app-argument=https://www.theguardian.com/world/2018/feb/27/ensuring-happier-lives-chinese-media-defends-move-to-make-xi-jinping-all-powerful, affiliate-data=ct=newsmartappbanner&pt=304191",
      "author": "Tom Phillips",
      "thumbnail": "https://i.guim.co.uk/img/media/5d33d9276cf4388564b5bf4d42e0cd4ad8ec221e/0_230_6835_4101/master/6835.jpg?w=620&q=55&auto=format&usm=12&fit=max&s=c857db05131da665271beb49d600180d",
      "news_keywords": "China,Xi Jinping,Asia Pacific,World news",
      "og:url": "http://www.theguardian.com/world/2018/feb/27/ensuring-happier-lives-chinese-media-defends-move-to-make-xi-jinping-all-powerful",
      "article:author": "https://www.theguardian.com/profile/tomphillips",
      "og:image:height": "720",
      "og:description": "United States declines to criticise removal of term limits as liberal thinkers inside China say move deserves to be ‘mocked by civilised countries’",
      "og:image:width": "1200",
      "og:image": "https://i.guim.co.uk/img/media/5d33d9276cf4388564b5bf4d42e0cd4ad8ec221e/0_230_6835_4101/master/6835.jpg?w=1200&h=630&q=55&auto=format&usm=12&fit=crop&crop=faces%2Centropy&bm=normal&ba=bottom%2Cleft&blend64=aHR0cHM6Ly91cGxvYWRzLmd1aW0uY28udWsvMjAxOC8wMS8zMS9mYWNlYm9va19kZWZhdWx0LnBuZw&s=391c7c897cafc35a55dd29b48ed544d5",
      "al:ios:url": "gnmguardian://world/2018/feb/27/ensuring-happier-lives-chinese-media-defends-move-to-make-xi-jinping-all-powerful?contenttype=Article&source=applinks",
      "article:publisher": "https://www.facebook.com/theguardian",
      "og:type": "article",
      "al:ios:app_store_id": "409128287",
      "article:section": "World news",
      "article:published_time": "2018-02-27T03:36:30.000Z",
      "og:title": "'Ensuring happier lives': Chinese media defends move to make Xi Jinping all powerful",
      "fb:app_id": "180444840287",
      "article:tag": "China,Xi Jinping,Asia Pacific,World news",
      "al:ios:app_name": "The Guardian",
      "og:site_name": "the Guardian",
      "article:modified_time": "2018-02-27T03:37:57.000Z",
      "twitter:app:id:iphone": "409128287",
      "twitter:app:name:googleplay": "The Guardian",
      "twitter:app:name:ipad": "The Guardian",
      "twitter:image": "https://i.guim.co.uk/img/media/5d33d9276cf4388564b5bf4d42e0cd4ad8ec221e/0_230_6835_4101/master/6835.jpg?w=1200&h=630&q=55&auto=format&usm=12&fit=crop&crop=faces%2Centropy&bm=normal&ba=bottom%2Cleft&blend64=aHR0cHM6Ly91cGxvYWRzLmd1aW0uY28udWsvMjAxOC8wMS8zMS90d2l0dGVyX2RlZmF1bHQucG5n&s=84952ae57ce9a937acbeb4ba307a1851",
      "twitter:site": "@guardian",
      "twitter:app:url:ipad": "gnmguardian://world/2018/feb/27/ensuring-happier-lives-chinese-media-defends-move-to-make-xi-jinping-all-powerful?contenttype=Article&source=twitter",
      "twitter:card": "summary_large_image",
      "twitter:app:name:iphone": "The Guardian",
      "twitter:app:id:ipad": "409128287",
      "twitter:app:id:googleplay": "com.guardian",
      "twitter:app:url:googleplay": "guardian://www.theguardian.com/world/2018/feb/27/ensuring-happier-lives-chinese-media-defends-move-to-make-xi-jinping-all-powerful",
      "twitter:app:url:iphone": "gnmguardian://world/2018/feb/27/ensuring-happier-lives-chinese-media-defends-move-to-make-xi-jinping-all-powerful?contenttype=Article&source=twitter",
      "twitter:dnt": "on",
      "fb:pages": "10513336322"
     }
    ],
    "newsarticle": [
     {
      "mainentityofpage": "https://www.theguardian.com/world/2018/feb/27/ensuring-happier-lives-chinese-media-defends-move-to-make-xi-jinping-all-powerful",
      "headline": "'Ensuring happier lives': Chinese media defends move to make Xi Jinping all powerful",
      "description": "United States declines to criticise removal of term limits as liberal thinkers inside China say move deserves to be ‘mocked by civilised countries’",
      "datepublished": "2018-02-26T22:36:30-0500",
      "datemodified": "2018-02-26T22:37:57-0500",
      "articlebody": "The Communist party’s decision to abolish presidential term limits – a move experts and critics have condemned as a lurch towards unchecked dictatorship in China – is designed to “ensure..."
     }
    ],
    "imageobject": [
     {
      "url": "https://uploads.guim.co.uk/2018/01/31/TheGuardian_AMP.png",
      "width": "190",
      "height": "60"
     },
     {
      "representativeofpage": "true",
      "url": "https://i.guim.co.uk/img/media/5d33d9276cf4388564b5bf4d42e0cd4ad8ec221e/0_230_6835_4101/master/6835.jpg?w=700&q=55&auto=format&usm=12&fit=max&s=fe7f74933d50ef2a656efe950160ba56",
      "width": "6835",
      "height": "4101",
      "contenturl": "https://i.guim.co.uk/img/media/5d33d9276cf4388564b5bf4d42e0cd4ad8ec221e/0_230_6835_4101/master/6835.jpg?w=300&q=55&auto=format&usm=12&fit=max&s=7b25be283cc4e2d1017f21fa387d7dd5",
      "description": "People walk past a poster of Chinese President Xi Jinping beside a street in Beijing. The Communist party has paved the way for him to assume the presidency indefinitely. Photograph: Greg Baker/AFP..."
     }
    ],
    "person": [
     {
      "sameas": "Tom Phillips",
      "name": "Tom Phillips"
     }
    ],
    "organization": [
     {
      "name": "The Guardian",
      "sameas": "https://www.theguardian.com/"
     }
    ],
    "cse_image": [
     {
      "src": "https://i.guim.co.uk/img/media/5d33d9276cf4388564b5bf4d42e0cd4ad8ec221e/0_230_6835_4101/master/6835.jpg?w=300&q=55&auto=format&usm=12&fit=max&s=7b25be283cc4e2d1017f21fa387d7dd5",
      "type": "1",
      "width": "290",
      "height": "174"
     }
    ]
   }
  },
  {
   "kind": "customsearch#result",
   "title": "China: Xi Jinping allowed to rule for ever - Europe Solidaire Sans ...",
   "htmlTitle": "\u003cb\u003eChina\u003c/b\u003e: \u003cb\u003eXi Jinping\u003c/b\u003e allowed to rule for ever - Europe Solidaire Sans ...",
   "link": "https://www.europe-solidaire.org/spip.php?article43289",
   "displayLink": "www.europe-solidaire.org",
   "snippet": "Feb 27, 2018 ... 'Ensuring happier lives': Chinese media defends move to make Xi Jinping all \npowerful. United States declines to criticise removal of term limits as liberal \nthinkers inside China say move deserves to be 'mocked by civilised countries'. \nThe Communist party's decision to abolish presidential term limits – a ...",
   "htmlSnippet": "Feb 27, 2018 \u003cb\u003e...\u003c/b\u003e '\u003cb\u003eEnsuring happier lives\u003c/b\u003e': \u003cb\u003eChinese media defends move\u003c/b\u003e to \u003cb\u003emake Xi Jinping all\u003c/b\u003e \u003cbr\u003e\n\u003cb\u003epowerful\u003c/b\u003e. \u003cb\u003eUnited States declines\u003c/b\u003e to \u003cb\u003ecriticise removal\u003c/b\u003e of \u003cb\u003eterm limits\u003c/b\u003e as \u003cb\u003eliberal\u003c/b\u003e \u003cbr\u003e\n\u003cb\u003ethinkers inside China say move deserves\u003c/b\u003e to be '\u003cb\u003emocked\u003c/b\u003e by \u003cb\u003ecivilised countries\u003c/b\u003e'. \u003cbr\u003e\nThe Communist party's decision to abolish presidential \u003cb\u003eterm limits\u003c/b\u003e – a ...",
   "cacheId": "xNfA2usjfGwJ",
   "formattedUrl": "https://www.europe-solidaire.org/spip.php?article43289",
   "htmlFormattedUrl": "https://www.europe-solidaire.org/spip.php?article43289",
   "pagemap": {
    "metatags": [
     {
      "viewport": "width=device-width, initial-scale=1.0"
     }
    ],
    "hcard": [
     {
      "fn": "PHILLIPS Tom",
      "url": "https://www.europe-solidaire.org/spip.php?auteur10557",
      "url_text": "PHILLIPS Tom"
     }
    ]
   }
  },
  {
   "kind": "customsearch#result",
   "title": "Xi Jinping | World | The Guardian",
   "htmlTitle": "\u003cb\u003eXi Jinping\u003c/b\u003e | World | The Guardian",
   "link": "https://www.theguardian.com/world/xi-jinping",
   "displayLink": "www.theguardian.com",
   "snippet": "1 day ago ... 'Ensuring happier lives': Chinese media defends move to make Xi Jinping all \npowerful. United States declines to criticise removal of term limits as liberal \nthinkers inside China say move deserves to be 'mocked by civilised countries'. \nPublished: 10:36 PM. 'Ensuring happier lives': Chinese media defends ...",
   "htmlSnippet": "1 day ago \u003cb\u003e...\u003c/b\u003e '\u003cb\u003eEnsuring happier lives': Chinese media defends move\u003c/b\u003e to \u003cb\u003emake Xi Jinping all\u003c/b\u003e \u003cbr\u003e\n\u003cb\u003epowerful\u003c/b\u003e. \u003cb\u003eUnited States declines\u003c/b\u003e to \u003cb\u003ecriticise removal\u003c/b\u003e of \u003cb\u003eterm limits\u003c/b\u003e as \u003cb\u003eliberal\u003c/b\u003e \u003cbr\u003e\n\u003cb\u003ethinkers inside China say move deserves\u003c/b\u003e to be '\u003cb\u003emocked\u003c/b\u003e by \u003cb\u003ecivilised countries\u003c/b\u003e'. \u003cbr\u003e\nPublished: 10:36 PM. '\u003cb\u003eEnsuring happier lives': Chinese media defends\u003c/b\u003e ...",
   "cacheId": "UjbuXbyQHKsJ",
   "formattedUrl": "https://www.theguardian.com/world/xi-jinping",
   "htmlFormattedUrl": "https://www.theguardian.com/world/\u003cb\u003exi\u003c/b\u003e-\u003cb\u003ejinping\u003c/b\u003e",
   "pagemap": {
    "cse_thumbnail": [
     {
      "width": "290",
      "height": "174",
      "src": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcToDkj5l17V62vsyZ0lkbCiH6Er9PEydDqKzxA7yPuOB5irCw3rceke9ks"
     }
    ],
    "metatags": [
     {
      "format-detection": "telephone=no",
      "handheldfriendly": "True",
      "viewport": "width=device-width,minimum-scale=1,initial-scale=1",
      "apple-mobile-web-app-title": "Guardian",
      "application-name": "The Guardian",
      "msapplication-tilecolor": "#e7edef",
      "theme-color": "#e7edef",
      "msapplication-tileimage": "https://assets.guim.co.uk/images/favicons/77beb32f01ee0157ec193e09e4e18c4e/windows_tile_144_b.png",
      "apple-itunes-app": "app-id=409128287, app-argument=https://www.theguardian.com/world/xi-jinping, affiliate-data=ct=newsmartappbanner&pt=304191",
      "og:url": "http://www.theguardian.com/world/xi-jinping",
      "al:ios:url": "gnmguardian://world/xi-jinping?contenttype=list&source=applinks",
      "og:type": "website",
      "al:ios:app_store_id": "409128287",
      "fb:app_id": "180444840287",
      "al:ios:app_name": "The Guardian",
      "og:site_name": "the Guardian",
      "twitter:app:id:iphone": "409128287",
      "twitter:app:name:googleplay": "The Guardian",
      "twitter:app:name:ipad": "The Guardian",
      "twitter:site": "@guardian",
      "twitter:app:url:ipad": "gnmguardian://world/xi-jinping?contenttype=list&source=twitter",
      "twitter:card": "summary",
      "twitter:app:name:iphone": "The Guardian",
      "twitter:app:id:ipad": "409128287",
      "twitter:app:id:googleplay": "com.guardian",
      "twitter:app:url:iphone": "gnmguardian://world/xi-jinping?contenttype=list&source=twitter",
      "twitter:dnt": "on",
      "fb:pages": "10513336322",
      "twitter:url": "https://www.theguardian.com/world/xi-jinping",
      "og:title": "Xi Jinping | World news | The Guardian"
     }
    ],
    "webpage": [
     {
      "keywords": "Asia Pacific"
     }
    ],
    "cse_image": [
     {
      "src": "https://i.guim.co.uk/img/media/07a39d19a47e2e87502cd64d2ea09cd841d59a4a/591_660_4794_2876/master/4794.jpg?w=300&q=55&auto=format&usm=12&fit=max&s=ea982bfe9f0599c02e30198d63d0a1a8"
     }
    ]
   }
  },
  {
   "kind": "customsearch#result",
   "title": "مارس 2015 – علوم انسانی olomeensani.com",
   "htmlTitle": "مارس 2015 – علوم انسانی olomeensani.com",
   "link": "http://olomeensani.com/2015/03",
   "displayLink": "olomeensani.com",
   "snippet": "30 مارس 2015 ... Kate Lamb in Jakarta; 'Ensuring happier lives': Chinese media defends move to \nmake Xi Jinping all powerful فوریه 27, 2018. United States declines to criticise \nremoval of term limits as liberal thinkers inside China say move deserves to be '\nmocked by civilised countries'The Communist party's decision to ...",
   "htmlSnippet": "30 مارس 2015 \u003cb\u003e...\u003c/b\u003e Kate Lamb \u003cb\u003ein\u003c/b\u003e Jakarta; '\u003cb\u003eEnsuring happier lives\u003c/b\u003e': \u003cb\u003eChinese media defends move\u003c/b\u003e to \u003cbr\u003e\n\u003cb\u003emake Xi Jinping all powerful\u003c/b\u003e فوریه 27, 2018. \u003cb\u003eUnited States declines\u003c/b\u003e to \u003cb\u003ecriticise\u003c/b\u003e \u003cbr\u003e\n\u003cb\u003eremoval\u003c/b\u003e of \u003cb\u003eterm limits\u003c/b\u003e as \u003cb\u003eliberal thinkers inside China say move deserves\u003c/b\u003e to be '\u003cbr\u003e\n\u003cb\u003emocked\u003c/b\u003e by \u003cb\u003ecivilised countries\u003c/b\u003e'The Communist party's decision to ...",
   "cacheId": "j9CqlbDCdQAJ",
   "formattedUrl": "olomeensani.com/2015/03",
   "htmlFormattedUrl": "olomeensani.com/2015/03",
   "pagemap": {
    "metatags": [
     {
      "viewport": "width=device-width, initial-scale=1",
      "msapplication-tileimage": "http://olomeensani.com/wp-content/uploads/2015/12/cropped-DSC_0187.JPG-e1449088658125-1-270x270.jpg"
     }
    ]
   }
  }
 ]
}

Edit-final:

You sir just made my day, happy to see this result,

Optional([Social_Login_api.Item(metatags: Optional([Social_Login_api.enclosedTags(image: Optional("https://i.guim.co.uk/img/media/5d33d9276cf4388564b5bf4d42e0cd4ad8ec221e/0_230_6835_4101/master/6835.jpg?w=1200&h=630&q=55&auto=format&usm=12&fit=crop&crop=faces%2Centropy&bm=normal&ba=bottom%2Cleft&blend64=aHR0cHM6Ly91cGxvYWRzLmd1aW0uY28udWsvMjAxOC8wMS8zMS9mYWNlYm9va19kZWZhdWx0LnBuZw&s=391c7c897cafc35a55dd29b48ed544d5"), title: Optional("\'Ensuring happier lives\': Chinese media defends move to make Xi Jinping all powerful"), description: Optional("United States declines to criticise removal of term limits as liberal thinkers inside China say move deserves to be ‘mocked by civilised countries’"), siteName: Optional("the Guardian"))]))

Lastly would you point out how to get rid of these annoying optional wordings before json extracted string?


Solution

  • In the code,

    struct Metadata: Decodable
    {
        var metatags: [enclosedTags]?
    }
    
    struct enclosedTags: Decodable
    {
        let image: String?
        let title: String?
        let description: String?
        let siteName: String?
    
        private enum CodingKeys : String, CodingKey
        {
            case image = "og:image", title = "og:title", description = "og:description", siteName = "og:site_name"
        }
    }
    
    1. It must be CodingKeys instead of codingKeys. It is "C" not "c"

    2. Also, the properties of the Codable Type i.e. Metadata and enclosedTags must be optional. You don't know what you will get from API. In case the properties are not optional and you don't get any one of the keys from API, the complete object will be nil.

    Edit:

    Use try? instead of try

    let tags = try? JSONDecoder().decode(Metadata.self, from: data)
    print(tags?.metatags)
    

    Expected JSON format:

          {
            "metatags": [
                     {
                      "og:description": "United States declines to criticise removal of term limits as liberal thinkers inside China say move deserves to be ‘mocked by civilised countries’",
                      "og:image": "https://i.guim.co.uk/img/media/5d33d9276cf4388564b5bf4d42e0cd4ad8ec221e/0_230_6835_4101/master/6835.jpg?w=1200&h=630&q=55&auto=format&usm=12&fit=crop&crop=faces%2Centropy&bm=normal&ba=bottom%2Cleft&blend64=aHR0cHM6Ly91cGxvYWRzLmd1aW0uY28udWsvMjAxOC8wMS8zMS9mYWNlYm9va19kZWZhdWx0LnBuZw&s=391c7c897cafc35a55dd29b48ed544d5",
                      "og:title": "'Ensuring happier lives': Chinese media defends move to make Xi Jinping all powerful",
                     }
                    ]
          }
    

    Sample code:

        let jsonString = """
        {
        "metatags": [
                 {
                  "og:description": "United States declines to criticise removal of term limits as liberal thinkers inside China say move deserves to be ‘mocked by civilised countries’",
                  "og:image": "https://i.guim.co.uk/img/media/5d33d9276cf4388564b5bf4d42e0cd4ad8ec221e/0_230_6835_4101/master/6835.jpg?w=1200&h=630&q=55&auto=format&usm=12&fit=crop&crop=faces%2Centropy&bm=normal&ba=bottom%2Cleft&blend64=aHR0cHM6Ly91cGxvYWRzLmd1aW0uY28udWsvMjAxOC8wMS8zMS9mYWNlYm9va19kZWZhdWx0LnBuZw&s=391c7c897cafc35a55dd29b48ed544d5",
                  "og:title": "'Ensuring happier lives': Chinese media defends move to make Xi Jinping all powerful",
                 }
                ]
            }
        """
    
        if let jsonData = jsonString.data(using: .utf8)
        {
            let obj = try? JSONDecoder().decode(Metadata.self, from: jsonData)
            print(obj?.metatags)
        }
    

    Output:

    [SampleNavigation.ViewController.enclosedTags(image: Optional("https://i.guim.co.uk/img/media/5d33d9276cf4388564b5bf4d42e0cd4ad8ec221e/0_230_6835_4101/master/6835.jpg?w=1200&h=630&q=55&auto=format&usm=12&fit=crop&crop=faces%2Centropy&bm=normal&ba=bottom%2Cleft&blend64=aHR0cHM6Ly91cGxvYWRzLmd1aW0uY28udWsvMjAxOC8wMS8zMS9mYWNlYm9va19kZWZhdWx0LnBuZw&s=391c7c897cafc35a55dd29b48ed544d5"), title: Optional("\'Ensuring happier lives\': Chinese media defends move to make Xi Jinping all powerful"), description: Optional("United States declines to criticise removal of term limits as liberal thinkers inside China say move deserves to be ‘mocked by civilised countries’"), siteName: nil)]
    

    Edit 2:

    struct Response: Decodable
    {
        var items: [Item]?
    }
    
    struct Item: Decodable
    {
        var pagemap: Pagemap?
    }
    
    struct Pagemap: Decodable
    {
        var metatags: [enclosedTags]?
    }
    
    struct enclosedTags: Decodable
    {
        let image: String?
        let title: String?
        let description: String?
        let siteName: String?
    
        private enum CodingKeys : String, CodingKey
        {
            case image = "og:image", title = "og:title", description = "og:description", siteName = "og:site_name"
        }
    }
    

    Decoding JSON:

        if let jsonData = jsonString.data(using: .utf8)
        {
            let obj = try? JSONDecoder().decode(Response.self, from: jsonData)
            print(obj?.items)
        }
    

    Edit 3:

    Instead of creating separate struct for pagemap, you can use containers for extracting nested information, i.e. you can use the following structs,

    struct Response: Decodable
    {
        var items: [Item]?
    }
    
    struct Item: Decodable
    {
        var metatags: [enclosedTags]?
    
        enum CodingKeys : String, CodingKey
        {
            case pagemap
        }
    
        enum PageMapKeys: String, CodingKey
        {
            case metatags
        }
    
        init(from decoder: Decoder) throws
        {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            let pagemap = try values.nestedContainer(keyedBy: PageMapKeys.self, forKey: .pagemap)
            metatags = try pagemap.decode([enclosedTags].self, forKey: .metatags)
        }
    }
    
    struct enclosedTags: Decodable
    {
        let image: String?
        let title: String?
        let description: String?
        let siteName: String?
    
        private enum CodingKeys : String, CodingKey
        {
            case image = "og:image", title = "og:title", description = "og:description", siteName = "og:site_name"
        }
    } 
    

    Let me know if you still face any issues. Happy Coding..🙂