Richard Sun
Richard Sun

Reputation: 69

JSON not able to parse with Codable

I'm trying to parse this json string:

let jsonString  = """
{
  "items": [
    {
      "snippet": {
        "publishedAt": "2020-05-20T16:00:23Z",
        "title": "Lesson 2 - One Day Build",
        "description": "Description for Lesson 2",
        "thumbnails": {
          "high": {
            "url": "https://i.ytimg.com/vi/PvvwZW-dRwg/sddefault.jpg",
            "width": 640,
            "height": 480
          },
          "maxres": {
            "url": "https://i.ytimg.com/vi/PvvwZW-dRwg/maxresdefault.jpg",
            "width": 1280,
            "height": 720
          }
        },
        "resourceId": {
          "videoId": "PvvwZW-dRwg"
        }
      }
    },
    {
      "snippet": {
        "publishedAt": "2020-05-26T16:00:23Z",
        "title": "Lesson 3 - One Day Build",
        "description": "Description for Lesson 3",
        "thumbnails": {
          "high": {
            "url": "https://i.ytimg.com/vi/m3XbTkMZMPE/sddefault.jpg",
            "width": 640,
            "height": 480
          },
          "maxres": {
            "url": "https://i.ytimg.com/vi/m3XbTkMZMPE/maxresdefault.jpg",
            "width": 1280,
            "height": 720
          }
        },
        "resourceId": {
          "videoId": "m3XbTkMZMPE"
        }
      }
    }
  ]
}
"""

I have these structs created (from QuickType):

// MARK: - Welcome
struct Welcome: Codable {
    let items: Item
}

// MARK: - Item
struct Item: Codable {
    let snippet: Snippet
}

// MARK: - Snippet
struct Snippet: Codable {
    let publishedAt: Date
    let title, snippetDescription: String
    let thumbnails: Thumbnails
    let resourceID: ResourceID
}

// MARK: - ResourceID
struct ResourceID: Codable {
    let videoID: String
}

// MARK: - Thumbnails
struct Thumbnails: Codable {
    let high, maxres: High
}

// MARK: - High
struct High: Codable {
    let url: String
    let width, height: Int
}

And I'm calling this function:

func ParseJson() {

    // Array for  the list of video objects
    var videos = [Video]()

    if let jsonData = jsonString.data(using: .utf8) {
        let decoder = JSONDecoder()
        
        do {
            let parsedJson = try decoder.decode(Welcome.self, from: jsonData)
            print("here")
        } catch {
            print(error.localizedDescription)
        }
      
      // Output the contents of the array
      dump(videos)
    } else {
      print("Error, unable to parse JSON")
    }
}

According to the tutorials and online resources I've found, as long as the structs are correct here, I should be able to decode the json string into the structs. The output is always "The operation could not be completed" which is from the catch statement. Any help is appreciated.

Thank you

Upvotes: 0

Views: 102

Answers (1)

Sweeper
Sweeper

Reputation: 270758

There are a bunch of errors in your code:

  • Welcome.items is an array of Items, not just one.
  • Snippet.publishedAt is in ISO 8601 format, so you need to set the dateDecodingStrategy of the decoder accordingly.
  • Misspelling of keys:
    • description, not snippetDescription
    • resourceId, not resouceID
    • videoId, not videoID

Here's the updated structs and decoding code:

// MARK: - Welcome
struct Welcome: Codable {
    let items: [Item]
}

// MARK: - Item
struct Item: Codable {
    let snippet: Snippet
}

// MARK: - Snippet
struct Snippet: Codable {
    let publishedAt: Date
    let title, description: String
    let thumbnails: Thumbnails
    let resourceId: ResourceID
}

// MARK: - ResourceID
struct ResourceID: Codable {
    let videoId: String
}

// MARK: - Thumbnails
struct Thumbnails: Codable {
    let high, maxres: High
}

// MARK: - High
struct High: Codable {
    let url: String
    let width, height: Int
}

if let jsonData = jsonString.data(using: .utf8) {
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .iso8601
    do {
        let parsedJson = try decoder.decode(Welcome.self, from: jsonData)
        print("here")
    } catch {
        print(error)
    }
} else {
  print("Error, unable to parse JSON")
}

Upvotes: 4

Related Questions