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