0

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

1
  • 2
    Don't print the localised description, print(error) to see exactly what the error is. Commented Nov 2, 2020 at 2:21

1 Answer 1

4

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")
}
Sign up to request clarification or add additional context in comments.

1 Comment

I would just change the name of the description property and provide a custom CodingKey

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.