UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Need help by parsing a youtube JSON API call

Forums > SwiftUI

Hello,

i am very new to App programming, and ich watched some tutotrials and made some simple Apps, but now i want to try to make an App which will show you your Youtube playlist. I want to parse the JSON Data from the Youtube API, but it doesnt show me anything :(

Maybe someone can help me? That would be great! :)

Here are my Code:

ContentView.swift

//
//  ContentView.swift
//  swiftui_youtube
//
//  Created by Markus Krakora on 21.06.21.
//

import SwiftUI

struct ContentView: View {
    @ObservedObject var viewModel: VideoListViewModel

    var body: some View {
        NavigationView {
            VStack {
                Text("Videos")
                Spacer()
                List(viewModel.videos) { video in
                    VideoView(video: video)
                }
            }
        }
    }
}

struct VideoView: View {
    @ObservedObject var video: VideoViewModel

    var body: some View {
        HStack {
            VStack(alignment: .leading) {
                Text(video.title)
                Text(video.description)
            }
        }
        .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(viewModel: VideoListViewModel())
    }
}

DataModelView.swift

//
//  DataModel.swift
//  swiftui_youtube
//
//  Created by Markus Krakora on 21.06.21.
//

import Foundation

protocol ModelDelegate {
    func videosFetched(_ videos:[Video])
}

class DataModel {

    var delegate:ModelDelegate?

    func getVideos() {

        // Create a URL object
        let url = URL(string: Constants.API_URL)

        guard url != nil else {
            return
        }

        // Get a URLSession object
        let session = URLSession.shared

        // Get a data task form the URLSession object
        let dataTask = session.dataTask(with: url!) { data, response, error in

            // check if there were any errors
            if (error != nil || data == nil) {
                return
            }

            do {

                // Parsing the data into video objects
                let decoder = JSONDecoder()
                decoder.dateDecodingStrategy = .iso8601

                let response = try decoder.decode(Response.self, from: data!)

                if (response.items != nil) {

                    DispatchQueue.main.async {
                        //Call the "videosFetched" method of the delegate
                        self.delegate?.videosFetched(response.items!)
                    }

                }

                dump(response)

            } catch {
                print("Error")
            }

        }

        // Kick off the task
        dataTask.resume()

    }
}

struct Response: Decodable {

    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)
    }
}

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 pusblished = "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 title
        self.title = try snippetContainer.decode(String.self, forKey: .title)

        //Parse description
        self.description = try snippetContainer.decode(String.self, forKey: .description)

        //Parse published
        self.published = try snippetContainer.decode(Date.self, forKey: .pusblished)

        //Parse thumbnails
        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 resourceIdContainer = try snippetContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .resourceId)

        self.videoId = try resourceIdContainer.decode(String.self, forKey: .videoId)

    }

}

VideoListViewModel.swift

//
//  VideoListViewModel.swift
//  swiftui_youtube
//
//  Created by Markus Krakora on 21.06.21.
//

import Combine
import Foundation
import SwiftUI

class VideoListViewModel: ObservableObject {

@Published public private(set) var videos: [VideoViewModel] = []
    private let dataModel: DataModel = DataModel()

    init() {
        dataModel.getVideos()
    }
}

class VideoViewModel: Identifiable, ObservableObject {

    let videoId: String
    let description: String
    let thumbnail: String
    let published: Date
    let title: String

    init(video: Video) {
        self.videoId = video.videoId
        self.description = video.description
        self.thumbnail = video.thumbnail
        self.published = video.published
        self.title = video.title

    }

}

Constants.swift

//
//  Constants.swift
//  swiftui_youtube
//
//  Created by Markus Krakora on 21.06.21.
//

import Foundation

struct Constants {

    static var API_KEY = "YOU_NEED_TO_USE_YOUR_OWN_YOUTUBE_API_KEY"
    static var PLAYLIST_ID = "UUHHmVREY2KkRkdP2o5jo5qQ"
    static var API_URL = "https://youtube.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=\(Constants.PLAYLIST_ID)&key=\(Constants.API_KEY)"
}

2      

Please provide some sample JSON data.

2      

You might want to take a look at Stewart Lynch's Channel-Watcher as he deals with YouTube

2      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.