Hi, I have a general question about the struct initializer methods used in the YouTube app one day build lessons. The initializer of the Video struct is declared as init (from decoder: Decoder), what is the form of initializer with the from in the parameters. I’m not quite understanding how this get called from the API logic to get and parse the data. Can someone please explain how this initializer works? My code works fine I’m just trying to fully understand this method. Thanks for the help in advance!
I haven’t been following that particular project, but usually that form of init
is used when decoding a JSON object into a struct or class. It is called automatically when you do something like:
let video = JSONDecoder().decode(Video.self, from: jsonData)
Hey Patrick,
This is the code that Kasey is referring too.
import Foundation
struct Video: Decodable {
var videoId = ""
var title = ""
var description = ""
var thumbnail = ""
var published = Date()
enum CodingKeys: String, CodingKey {
case snippet
case thumbnails
case high
case resourceId
case published = "publishedAt"
case title
case description
case thumbnail = "url"
case videoId
}
init (from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let snippetContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .snippet)
// Parse the title
title = try snippetContainer.decode(String.self, forKey: .title)
// Parse the description
description = try snippetContainer.decode(String.self, forKey: .description)
// Parse the published date
published = try snippetContainer.decode(Date.self, forKey: .published)
// Parse the thumbnail
let thumbnailContainer = try snippetContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .thumbnails)
let highContainer = try thumbnailContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .high)
thumbnail = try highContainer.decode(String.self, forKey: .thumbnail)
// Parse videoId
let resourceIdContainer = try snippetContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .resourceId)
videoId = try resourceIdContainer.decode(String.self, forKey: .videoId)
}
}
I did the course too but looked at that and thought…
I looked up the developer documentation for the decodable protocol. This is the required form of the initializer for the protocol, it’s expecting the decoder type which in this case happens to be the [Video] array that conforms to the decodable protocol. I’m very new to this JSON thing so much of this is taking me some time to wrap my head around. I’m slowly grasping the nesting nature of JSON, how it decodes from a Response type which is composed of Video types. Thanks for the replies, I’ll try to do better research in the documentation next time before posting.
@Kharbuck29
I’d recommend following these two tutorials. They will give you a way better idea of what JSON is and what the YouTube video is trying to accomplish
Thanks! I’ll check these out.