TMDb api call - Swift - ios

I'm calling the TMDb Api to get an array of movies by genre. I'm getting 'nil' back on many of the properties I want to access such as "vote_count", "poster_path" and "vote_average".
If I call the api in a browser I get all of the properties as expected.
Here's my model:
import Foundation
// MARK: - MovieList
struct MovieList: Codable {
let page: Int
let totalResults: Int?
let totalPages: Int?
let results: [Result]
enum CodingKeys: String, CodingKey {
case page
case totalResults = "total_results"
case totalPages = "total_pages"
case results
}
}
// MARK: - Result
struct Result: Codable {
let popularity: Double?
let voteCount: Int?
let video: Bool?
let posterPath: String?
let id: Int?
let adult: Bool?
let backdropPath: String?
let originalLanguage: OriginalLanguage?
let originalTitle: String?
let genreIDS: [Int]?
let title: String?
let voteAverage: Double?
let overview, releaseDate: String?
enum CodingKeys: String, CodingKey {
case popularity
case voteCount = "vote_count"
case video
case posterPath = "poster_path"
case id, adult
case backdropPath = "backdrop_path"
case originalLanguage = "original_language"
case originalTitle = "original_title"
case genreIDS = "genre_ids"
case title
case voteAverage = "vote_average"
case overview
case releaseDate = "release_date"
}
}
enum OriginalLanguage: String, Codable {
case en = "en"
case es = "es"
}
Here's the networking call:
func getMovieDetails(movie: Int, completion: #escaping (Result?) -> ()) {
guard let url = URL(string: "https://api.themoviedb.org/3/movie/157336?api_key=6228bff945f7bd2m18c04fc3839829c0") else {
fatalError("Invalid URL")
}
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: url) { data, response, error in
// Check for errors
guard error == nil else {
print ("error: \(error!)")
return
}
// Check that data has been returned
guard let data = data else {
print("No data")
return
}
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let movieDetails = try decoder.decode(Result.self, from: data)
DispatchQueue.main.async {
completion(movieDetails)
print(movieDetails)
}
} catch let err {
print("Err", err)
}
}
// execute the HTTP request
task.resume()
}
}
And here is the response:
MovieList(page: 1, totalResults: nil, totalPages: nil, results: [QuickFlicks.Result(popularity: Optional(171.78), voteCount: nil, video: Optional(false), posterPath: nil, id: Optional(454626), adult: Optional(false), backdropPath: nil, originalLanguage: nil, originalTitle: nil, genreIDS: nil, title: Optional("Sonic the Hedgehog"), voteAverage: nil, overview: Optional("Based on the global blockbuster videogame franchise from Sega, Sonic the Hedgehog tells the story of the world’s speediest hedgehog as he embraces his new home on Earth. In this live-action adventure comedy, Sonic and his new best friend team up to defend the planet from the evil genius Dr. Robotnik and his plans for world domination."), releaseDate: nil)])
Any help would be appreciated. Thank you.

You are giving contradicting instructions to the decoder, first you have the CodingKeys enum that say for instance that the posterPath property should be read from the poster_path key but then you set keyDecodingStrategy = .convertFromSnakeCase which means that the decoder first translates the key poster_path to posterPath before trying to match the key to a property.
So either remove decoder.keyDecodingStrategy = .convertFromSnakeCase or remove the CodingKeys enum

Related

How to debug JSONDecoder when no errors show?

I'm building a Swift app and testing in an Xcode Playground. Calling the NYTimes Search API and trying to store its response in a struct. The code executes cleanly and no errors appear (I am using a do, try, catch), but I cannot print any properties from the resulting object (print(json.status)).
My hunch is that something is fishy with this line but I'm not sure what since no errors are printing from the catch statement
let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: { data, response, error in
Form the URL endpoint to make the API call:
func APICall() {
let APIKey = "MY_API_KEY_GOES_HERE_BUT_IT'S_A_SECRET"
let searchTerm = "A Super Bowl Sideshow: See the Ageless Man!"
// Remove the spaces and convert them to percents
guard let encodedSearchTerm = searchTerm.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
else {
print("Error encoding search term in URL")
return
}
let url = "https://api.nytimes.com/svc/search/v2/articlesearch.json?q=" + encodedSearchTerm + "&api-key=" + APIKey
getData(from: url)
}
Data Task:
func getData(from url: String) {
//I believe something is wrong with the following line but I'm not sure what it is
let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: { data, response, error in
guard let data = data, error == nil else {
print("Error loading data")
return
}
var result: NYTSearchResponse?
do {
result = try JSONDecoder().decode(NYTSearchResponse.self, from: data)
} catch {
print(error)
}
guard let json = result else {
print("Error assigning result to json")
return
}
//Try to print these from the resulting object but these commands do not print
print(json.status)
print(json.response.docs[0].abstract)
})
task.resume()
}
My NYTSearchResponse struct which mirrors the NYT API JSON response. It's pretty complicated, but I pasted the json response into https://app.quicktype.io/ to build the struct.
// MARK: - Welcome
struct NYTSearchResponse: Codable {
let status, copyright: String
let response: Response
}
// MARK: - Response
struct Response: Codable {
let docs: [Doc]
let meta: Meta
}
// MARK: - Doc
struct Doc: Codable {
let abstract: String
let webURL: String
let snippet, leadParagraph, printSection, printPage: String
let source: String
let multimedia: [Multimedia]
let headline: Headline
let keywords: [Keyword]
let pubDate: Date
let documentType, newsDesk, sectionName, subsectionName: String
let byline: Byline
let typeOfMaterial, id: String
let wordCount: Int
let uri: String
enum CodingKeys: String, CodingKey {
case abstract
case webURL = "web_url"
case snippet
case leadParagraph = "lead_paragraph"
case printSection = "print_section"
case printPage = "print_page"
case source, multimedia, headline, keywords
case pubDate = "pub_date"
case documentType = "document_type"
case newsDesk = "news_desk"
case sectionName = "section_name"
case subsectionName = "subsection_name"
case byline
case typeOfMaterial = "type_of_material"
case id = "_id"
case wordCount = "word_count"
case uri
}
}
// MARK: - Byline
struct Byline: Codable {
let original: String
let person: [Person]
let organization: String?
}
// MARK: - Person
struct Person: Codable {
let firstname: String
let middlename: String?
let lastname: String
let qualifier, title: String?
let role, organization: String
let rank: Int
}
// MARK: - Headline
struct Headline: Codable {
let main: String
let kicker, contentKicker: String?
let printHeadline: String
let name, seo, sub: String?
enum CodingKeys: String, CodingKey {
case main, kicker
case contentKicker = "content_kicker"
case printHeadline = "print_headline"
case name, seo, sub
}
}
// MARK: - Keyword
struct Keyword: Codable {
let name, value: String
let rank: Int
let major: String
}
// MARK: - Multimedia
struct Multimedia: Codable {
let rank: Int
let subtype: String
let caption, credit: String?
let type, url: String
let height, width: Int
let legacy: Legacy
let subType, cropName: String
enum CodingKeys: String, CodingKey {
case rank, subtype, caption, credit, type, url, height, width, legacy, subType
case cropName = "crop_name"
}
}
// MARK: - Legacy
struct Legacy: Codable {
let xlarge: String?
let xlargewidth, xlargeheight: Int?
}
// MARK: - Meta
struct Meta: Codable {
let hits, offset, time: Int
}
I moved the code out of the playground and it works.

Missing argument for parameter 'from' in call - SwiftUI

I'm building a SwiftUI app that retrieves an array of movies by genre from The Movie Database API.
Once the user selects a movie, I make a second API to get details for that specific movie. I'm using #Published to notify the view of changes however I am getting the I get the error "Missing argument for parameter 'from' in call" whenever I call an instance of the Model.
Here's the Model:
import Foundation
// MARK: - MovieList
struct MovieList: Codable {
let page: Int
let totalResults: Int
let totalPages: Int
let movie: [Movie]
enum CodingKeys: String, CodingKey {
case page
case totalResults = "total_results"
case totalPages = "total_pages"
case movie = "results"
}
}
// MARK: - Movie
struct Movie: Codable {
let popularity: Double
let voteCount: Int
let video: Bool
let posterPath: String?
let id: Int
let adult: Bool
let backdropPath: String?
let title: String
let voteAverage: Double
let overview: String
let releaseDate: String?
let runTime: Int?
enum CodingKeys: String, CodingKey {
case popularity
case voteCount = "vote_count"
case video
case posterPath = "poster_path"
case id, adult
case backdropPath = "backdrop_path"
case title
case voteAverage = "vote_average"
case overview
case releaseDate = "release_date"
case runTime = "runtime"
}
}
And here's the View Model:
import Foundation
class DetailViewModel: ObservableObject {
#Published var fetchedMovie = Movie() // getting error here
func getMovieDetails(id: Int) {
WebService().getMovieDetails(movie: id) { movie in
if let movieDetails = movie {
self.fetchedMovie = movieDetails
}
}
}
}
And here's the network call:
func getMovieDetails(movie: Int, completion: #escaping (Movie?) -> ()) {
guard let url = URL(string: "https://api.themoviedb.org/3/movie/\(movie)?api_key=5228bff935f7bd2b18c04fc3633828c0") else {
fatalError("Invalid URL")
}
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: url) { data, response, error in
// Check for errors
guard error == nil else {
print ("error: \(error!)")
return
}
// Check that data has been returned
guard let data = data else {
print("No data")
return
}
do {
let decoder = JSONDecoder()
let movieDetails = try decoder.decode(Movie.self, from: data)
DispatchQueue.main.async {
completion(movieDetails)
}
} catch let err {
print("Err", err)
}
}
// execute the HTTP request
task.resume()
}
}
And the View code:
import SwiftUI
struct MovieDetailView: View {
#ObservedObject private var detailVM = DetailViewModel() // error here: Missing argument for parameter 'movie' in call
var movie: DetailViewModel
var body: some View {
VStack {
URLImage(url: "\(movie.backdropURL)")
.aspectRatio(contentMode: .fit)
Text("\(detailVM.movieRunTime) mins")
Text(movie.movieOverview)
.padding()
Spacer()
}.onAppear {
self.detailVM.getMovieDetails(id: self.movie.id)
}
.navigationBarTitle(movie.movieTitle)
}
}
struct MovieDetailView_Previews: PreviewProvider {
static var previews: some View {
MovieDetailView(movie: DetailViewModel(movie: Movie.example))
}
}
Any help would be greatly appreciated.
You cant initialise Movie object like this ... it needs Decoder object or all member wise intialization ---
You can define your function like this
class DetailViewModel: ObservableObject {
#Published var fetchedMovie : Movie?
func getMovieDetails(id: Int) {
WebService().getMovieDetails(movie: id) { movie in
if let movieDetails = movie {
self.fetchedMovie = movieDetails
}
}
}
}

Result of call to 'updateWeatherIcon(condition:)' is unused and therefore will not show UIImage

I am building a small Weather app that is accessing the openweathermap API. I am using JSONDecoder to parse the JSON from the API. For the most part, I am able to get most of the data in the simulator. Except for the UIImage that is supposed to appear on the screen. The image is in the image.xcassets. Below is the struct.
import UIKit
import CoreLocation
struct WeatherData: Codable {
let coord: Coord
let weather: [Weather]
let base: String
let main: Main
let visibility: Int
let wind: Wind
let clouds: Clouds
let dt: Int
let sys: Sys
let id: Int
let name: String
let cod: Int
}
struct Clouds: Codable {
let all: Int
}
struct Coord: Codable {
let lon, lat: Double
}
struct Main: Codable {
let temp: Double
let pressure, humidity: Int
let tempMin, tempMax: Double
// enum CodingKeys: String, CodingKey {
// case temp, pressure, humidity
// case tempMin = "temp_min"
/ / case tempMax = "temp_max"
// }
}
struct Sys: Codable {
let type, id: Int
let message: Double
let country: String
let sunrise, sunset: Int
}
struct Weather: Codable {
let id: Int
let main, description, icon: String
}
struct Wind: Codable {
let speed: Double
let deg: Int
}
The code that accesses that passes the JSON is below:
private func getWeatherData(parameters: [String : String]) {
guard let lat = parameters["lat"],
let long = parameters["long"],
let appID = parameters["appid"] else { print("Invalid parameters"); return }
var urlComponents = URLComponents(string: "https://api.openweathermap.org/data/2.5/weather")!
let queryItems = [URLQueryItem(name: "lat", value: lat),
URLQueryItem(name: "lon", value: long),
URLQueryItem(name: "appid", value: appID)]
urlComponents.queryItems = queryItems
guard let url = urlComponents.url else { return }
URLSession.shared.dataTask(with: url) { ( data, response, err ) in
DispatchQueue.main.async { // never, never, never sync !!
if let err = err {
print("Failed to get data from url:", err)
return
}
guard let data = data else { return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let city = try decoder.decode(WeatherData.self, from: data)
print(city)
//self.updateWeatherData(city)
self.weatherData.description = city.weather[0].main
self.weatherData.temperature = Int(city.main.temp - 273)
self.weatherData.city = city.name
self.weatherData.condition = city.weather[0].id
WeatherDataModel().updateWeatherIcon(condition: self.weatherData.condition)
self.updateUIWeatherData()
} catch {
print(error)
self.cityLabel.text = "Connection issues"
}
}
}.resume()
}
and the function that show the data on the simulator is:
func updateUIWeatherData() {
cityLabel.text = weatherData.city
temperatureLabel.text = String(weatherData.temperature)
decriptionLabel.text = String(weatherData.description)
weatherIcon.image = UIImage(named: weatherData.weatherIconName)
}
I have looked at other example of this waring and not really sure what this means in reference to this app.
Example of result of call is unused.
Any help would be appreciated.
It seems to me like you want the line
self.weatherData.weatherIconName = WeatherDataModel().updateWeatherIcon(condition: self.weatherData.condition)
instead of
WeatherDataModel().updateWeatherIcon(condition: self.weatherData.condition)
The warning is saying you're calculating the weatherIcon, but it's not being assigned to anything (your weatherData variable)

Type 'MyWeather' does not conform to protocol 'Encodable' error

I'm trying to make an iOS app that uses the OpenWeatherMap API to check the current weather, but I'm getting an error saying 'Type 'MyWeather' does not conform to protocol 'Encodable''. I am new to Swift Programming and it's probably a simple mistake. I would appreciate any help, thank you.
My code below:
struct MyWeather: Codable {
let name: String?
let location: String?
let temp: URL?
let wind: Int?
//THE NAMES OF THE JSON STUFF IN THE LINK
private enum CodingKeys: String, CodingKey {
case weather
case name
case location
case temp
case wind
//THE NAMES OF THE JSON STUFF IN THE LINK
}
}
class ViewController: UIViewController {
#IBAction func ShowWeatherInfo(_ sender: Any) {
guard let APIUrl = URL(string: "http://api.openweathermap.org/data/2.5/weather?q=Crowland&appid=APIKEY&units=Metric") else { return }
URLSession.shared.dataTask(with: APIUrl) { (data, response
, error) in
guard let data = data else { return }
do {
let decoder = JSONDecoder()
let weatherData = try decoder.decode(MyWeather.self, from: data)
You need to remove this
case weather
as there is no var for it also use CodingKeys only if you'll change key name , the Codable for the official json is
struct MyWeather: Codable {
let cod: String
let message: Double
let cnt: Int
let list: [List]
let city: City
}
struct City: Codable {
let id: Int
let name: String
let coord: Coord
let country: String
}
struct Coord: Codable {
let lat, lon: Double
}
struct List: Codable {
let dt: Int
let main: MainClass
let weather: [Weather]
let clouds: Clouds
let wind: Wind
let sys: Sys
let dtTxt: String
let rain, snow: Rain?
enum CodingKeys: String, CodingKey {
case dt, main, weather, clouds, wind, sys
case dtTxt = "dt_txt"
case rain, snow
}
}
struct Clouds: Codable {
let all: Int
}
struct MainClass: Codable {
let temp, tempMin, tempMax, pressure: Double
let seaLevel, grndLevel: Double
let humidity: Int
let tempKf: Double
enum CodingKeys: String, CodingKey {
case temp
case tempMin = "temp_min"
case tempMax = "temp_max"
case pressure
case seaLevel = "sea_level"
case grndLevel = "grnd_level"
case humidity
case tempKf = "temp_kf"
}
}
struct Rain: Codable {
let the3H: Double?
enum CodingKeys: String, CodingKey {
case the3H = "3h"
}
}
struct Sys: Codable {
let pod: Pod
}
enum Pod: String, Codable {
case d = "d"
case n = "n"
}
struct Weather: Codable {
let id: Int
let main: MainEnum
let description: Description
let icon: String
}
enum Description: String, Codable {
case brokenClouds = "broken clouds"
case clearSky = "clear sky"
case fewClouds = "few clouds"
case lightRain = "light rain"
case moderateRain = "moderate rain"
}
enum MainEnum: String, Codable {
case clear = "Clear"
case clouds = "Clouds"
case rain = "Rain"
}
struct Wind: Codable {
let speed, deg: Double
}

Append into array from JSON API

How can I append into an array using JSON Model Class.
Here is my JSON API Request: https://developer.github.com/v3/search/
import Foundation
typealias GitDecode = [GitDecodeElement]
struct GitDecodeElement: Codable {
let totalCount: Int
let incompleteResults: Bool
let items: [Item]
enum CodingKeys: String, CodingKey {
case totalCount = "total_count"
case incompleteResults = "incomplete_results"
case items
}
}
struct Item: Codable {
let id: Int
let nodeID, name, fullName: String
let owner: Owner
let itemPrivate: Bool
let htmlURL, description: String
let fork: Bool
let url, createdAt, updatedAt, pushedAt: String
let homepage: String
let size, stargazersCount, watchersCount: Int
let language: String
let forksCount, openIssuesCount: Int
let masterBranch, defaultBranch: String
let score: Double
enum CodingKeys: String, CodingKey {
case id
case nodeID = "node_id"
case name
case fullName = "full_name"
case owner
case itemPrivate = "private"
case htmlURL = "html_url"
case description, fork, url
case createdAt = "created_at"
case updatedAt = "updated_at"
case pushedAt = "pushed_at"
case homepage, size
case stargazersCount = "stargazers_count"
case watchersCount = "watchers_count"
case language
case forksCount = "forks_count"
case openIssuesCount = "open_issues_count"
case masterBranch = "master_branch"
case defaultBranch = "default_branch"
case score
}
}
struct Owner: Codable {
let login: String
let id: Int
let nodeID, avatarURL, gravatarID, url: String
let receivedEventsURL, type: String
enum CodingKeys: String, CodingKey {
case login, id
case nodeID = "node_id"
case avatarURL = "avatar_url"
case gravatarID = "gravatar_id"
case url
case receivedEventsURL = "received_events_url"
case type
}
}
And here I have my class Model where I'm saying what I want to extract from that response:
import Foundation
struct Git: Codable{
let totalCount: Int
let items: GitItem
init ( totalCount: Int,
itemID: Int, itemDescription: String,
ownerID: Int, ownerAvatarURL: String) {
self.totalCount = totalCount
self.items = GitItem(id: itemID, description: itemDescription, owner: GitOwner(id: ownerID, avatarURL: ownerAvatarURL))
}
}
struct GitItem: Codable{
let id: Int
let description: String
let owner: GitOwner
}
struct GitOwner: Codable {
let id: Int
let avatarURL: String
}
Now I'm stuck when I try to append into my array all my custom properties because itemID, itemDescription, ownerID and ownerAvatarURL are in different classes.
Here is how I'm trying to get all the that properties from JSON using JSONDecoder:
import UIKit
class MainViewController: UIViewController {
var gitRepositoriesArray = [Git]()
override func viewDidLoad() {
super.viewDidLoad()
}
// Download Git Repositories from API
func parseGitRepositories(){
let url = URL(string: "https://developer.github.com/v3/search/")
URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error == nil{
do{
let gitRepositoriesList = try JSONDecoder().decode(GitDecode.self, from: data!)
for eachRepo in gitRepositoriesList{
self.gitRepositoriesArray.append(Git(totalCount: eachRepo.totalCount,
itemID: <#T##Int#> , itemDescription: <#T##String#>, ownerID: <#T##Int#>, ownerAvatarURL: <#T##String#>))
}
}catch{
print(error.localizedDescription)
}
}
}.resume()
}
}
Complete working playground code:
Makes a search against the API for Swift related repos.
Parses them, adds them to the array and prints out some basic information on each one. (fullName, name, avatarUrl
//: Playground - noun: a place where people can play
import PlaygroundSupport
import UIKit
struct GitDecodeElement: Codable {
let totalCount: Int
let incompleteResults: Bool
let items: [Repo]
enum CodingKeys: String, CodingKey {
case totalCount = "total_count"
case incompleteResults = "incomplete_results"
case items
}
}
struct Repo: Codable {
let id: Int
let nodeID, name, fullName: String
let owner: Owner
let itemPrivate: Bool
let htmlURL, description: String
let fork: Bool
let url, createdAt, updatedAt, pushedAt: String
let homepage: String?
let size, stargazersCount, watchersCount: Int
let language: String?
let forksCount, openIssuesCount: Int
let score: Double
enum CodingKeys: String, CodingKey {
case id
case nodeID = "node_id"
case name
case fullName = "full_name"
case owner
case itemPrivate = "private"
case htmlURL = "html_url"
case description, fork, url
case createdAt = "created_at"
case updatedAt = "updated_at"
case pushedAt = "pushed_at"
case homepage, size
case stargazersCount = "stargazers_count"
case watchersCount = "watchers_count"
case language
case forksCount = "forks_count"
case openIssuesCount = "open_issues_count"
case score
}
}
struct Owner: Codable {
let login: String
let id: Int
let nodeID, avatarURL, gravatarID, url: String
let receivedEventsURL, type: String
enum CodingKeys: String, CodingKey {
case login, id
case nodeID = "node_id"
case avatarURL = "avatar_url"
case gravatarID = "gravatar_id"
case url
case receivedEventsURL = "received_events_url"
case type
}
}
var gitRepositoriesArray = [Repo]()
// Download Git Repositories from API
func parseGitRepositories() {
let url = URL(string: "https://api.github.com/search/repositories?q=topic:swift+topic:ios")
var request = URLRequest(url: url!)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard error == nil else {
print(error?.localizedDescription)
return
}
do {
let gitRepositoriesList = try JSONDecoder().decode(GitDecodeElement.self, from: data!)
gitRepositoriesArray = gitRepositoriesArray + gitRepositoriesList.items
print(gitRepositoriesArray.count)
for repo in gitRepositoriesList.items {
print("\(repo.fullName) - \(repo.name) - \(repo.owner.avatarURL)")
}
} catch {
let str = String(data: data!, encoding: .utf8)
print(str)
print(error)
}
}.resume()
}
parseGitRepositories()
PlaygroundPage.current.needsIndefiniteExecution = true
Output:
30
justjavac/free-programming-books-zh_CN - free-programming-books-zh_CN - https://avatars1.githubusercontent.com/u/359395?v=4
dkhamsing/open-source-ios-apps - open-source-ios-apps - https://avatars0.githubusercontent.com/u/4723115?v=4
matteocrippa/awesome-swift - awesome-swift - https://avatars2.githubusercontent.com/u/475463?v=4
xitu/gold-miner - gold-miner - https://avatars2.githubusercontent.com/u/10482599?v=4
lkzhao/Hero - Hero - https://avatars1.githubusercontent.com/u/3359850?v=4
ReactiveX/RxSwift - RxSwift - https://avatars1.githubusercontent.com/u/6407041?v=4
realm/realm-cocoa - realm-cocoa - https://avatars0.githubusercontent.com/u/7575099?v=4
CocoaPods/CocoaPods - CocoaPods - https://avatars1.githubusercontent.com/u/1189714?v=4
CosmicMind/Material - Material - https://avatars1.githubusercontent.com/u/10069574?v=4
// rest truncated
Notice how I use less models than you do in your code. There is no need to duplicate code, just use the parts you want, when you want them.
There is some problem in you Git structure. I have corrected the initializer like this:
struct Git: Codable{
let totalCount: Int
var items = [GitItem]()
init(totalCount: Int, items: [Item]) {
self.totalCount = totalCount
for item in items {
self.items.append(GitItem(id: item.id, description: item.description, owner: GitOwner(id: item.owner.id, avatarURL: item.owner.avatarURL)))
}
}
So your parsing method will be changed accordingly:
// Download Git Repositories from API
func parseGitRepositories(){
let url = URL(string: "https://api.github.com/search/repositories?q=tetris+language:assembly&sort=stars&order=desc")
URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error == nil{
do{
let gitRepositoriesList = try JSONDecoder().decode(GitDecode.self, from: data!)
for eachRepo in gitRepositoriesList{
self.gitRepositoriesArray.append(Git(totalCount: eachRepo.totalCount, items: eachRepo.items))
}
}catch{
print(error.localizedDescription)
}
}
}.resume()
}
Also note the change of url to https://api.github.com/search/repositories?q=tetris+language:assembly&sort=stars&order=desc. The current url that your are using in your code is just the html page with examples. It doesn't return proper json results.

Resources