I’m trying to practise by specifying a return type like “func getVideos() -> [Video]” but not use customized protocol. I can’t return the proper value in “Model” class. Could anyone please advise why I don’t get any return value at the end? The print log shows response.items! has a count of 5 and generatedVideos(the line below response.items!) has a count of 5 as well, but it shows generatedVideos(at the last line) has a count of 0. Could anyone help on this? Thank you.
Here is my code:
*/
import Foundation
class Model {
func getVideos() -> [Video] {
// Create a video array
var generatedVideos = [Video]()
let url = URL(string: Constants.API_URL)
let session = URLSession.shared
let dataTask = session.dataTask(with: url!) { (data, response, error) in
if data == nil || error != nil {
return
}
// Parsing the data into video objects
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
do {
let response = try decoder.decode(Response.self, from: data!)
if response.myItems != nil {
generatedVideos.append(contentsOf: response.myItems!)
}
// dump(response)
}
catch {
}
}
dataTask.resume()
return generatedVideos
}
You should put something in your catch block to let you know what error(s) are being encountered. That’s what catch blocks are for, after all.
Without knowing what errors you are getting, it’s pretty unlikely any of us can help. My guess, though, would be that there is an issue with how the Response struct is set up for initialization from JSON. It would be useful if you showed us the declaration for Response.
roosterboy, thanks for your reply. The error, or the roadblock I’m encountering is, I try to set a return value “func getVideos() -> [Video] { }” instead of using custom protocol that Chris taught. But I can’t get any [Video] returned. I will share my code for View Controller, Model, and Response.
Model code:
import Foundation
class Model {
func getVideos() -> [Video] {
var generatedVideos = [Video]()
// Get an url object
let url = URL(string: Constants.API_URL)
// Get an URLSession
let session = URLSession.shared
// Create a data task
let dataTask = session.dataTask(with: url!) { (data, response, error) in
if data == nil || error != nil {
return
}
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
do {
let response = try decoder.decode(Response.self, from: data!)
generatedVideos = response.items!
}
catch {
return
}
}
// Kick off data task
dataTask.resume()
return generatedVideos
}
}
View Controller Code:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
let model = Model()
var videosArray = [Video]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
videosArray = model.getVideos()
tableView.dataSource = self
tableView.delegate = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return videosArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Get a cell
let cell = tableView.dequeueReusableCell(withIdentifier: Constants.VIDEOCELL_ID, for: indexPath) as! VideoTableViewCell
// Configure the cell
cell.configureCell(videosArray[indexPath.row])
// Return the cell
return cell
}
}
Response Code:
import Foundation
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)
}