I am attempting to dynamically show the contents of YouTube playlist in my SwiftUI IOS app.
I have managed to obtain the relevant information from the API call but am struggling with the leap to saving the items as an array of Videos to then show in the SwiftUI view. The response itself at the moment is a list of videos.
Video Model
struct Video: Decodable, Hashable { var title = "" var description = "" var thumbnail = "" var videoId = "" // map variables to coded properties in JSON enum CodingKeys: String, CodingKey { // additional higher level keys so that we can access the nested variables case snippet case thumbnails case high case resourceId // general keys - have to make sure these match the JSON keys case videoId case title case description case thumbnail = "url" } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let snippetContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .snippet) // parse title self.title = try snippetContainer.decode(String.self, forKey: .title) // parse description self.description = try snippetContainer.decode(String.self, forKey: .description) // parse thumbnail - needed to drill down into further nests let thumbnailContainer = try snippetContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .thumbnails) let highContainer = try thumbnailContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .high) self.thumbnail = try highContainer.decode(String.self, forKey: .thumbnail) // parse videoId let resourceContainer = try snippetContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .resourceId) self.videoId = try resourceContainer.decode(String.self, forKey: .videoId) }}// the containers that are referenced above are in a items dictionary in the high levelstruct Response: Decodable, Hashable { var items: [Video]? enum CodingKeys: String, CodingKey { case items } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.items = try container.decode([Video].self, forKey: .items) }}
View Model (the response prints)
class VideoModel: ObservableObject { func getVideos() { // create a URL object let url = URL(string: Constants.API_URL) //return if the API_url is blank guard url != nil else { return } // get a URLsession object let session = URLSession.shared // get a data task from URLsession object let dataTask = session.dataTask(with: url!) {(data, response, error) in // check if there is an error if error != nil || data == nil { return} do { // parsing the data into video objects let decorder = JSONDecoder() let response = try decorder.decode(Response.self, from: data!) } catch { print(error) } } dataTask.resume() }}
SwiftUI view - incomplete as new to create a row view.
struct PlayListView: View { var viewModel = VideoModel() var body: some View { NavigationView { ScrollView { List { ForEach(viewModel.response.items, id: \.self) { video in Text(video.title) } } } .navigationTitle("The GB Way") .onAppear() { viewModel.getVideos() } } }}
Thank you in advance for any help