I am parsing JSON from a subreddit in Swift. The URL is:
https://www.reddit.com/r/cat/top.json
The objects are returning nil (print me in console "Your TableView did not load data")
I feel like perhaps my nesting is incorrect or something with the network call, thanks.
struct GalleryData: Codable {
let data: ListingData
}
struct ListingData: Codable {
let children: [Child]
}
struct Child: Codable {
let data: ChildData
}
struct ChildData: Codable {
let subreddit: String
let author: String
let title: String
let thumbnail: String
let url_overridden_by_dest: String
}
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var dataArray = [GalleryData]()
let baseURL = "https://www.reddit.com/r/"
// START SEARCHBAR
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var labelError: UILabel!
var filteredArray = [GalleryData]() {
didSet {
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
// END SEARCHBAR
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
// START SEARCHBAR
searchBar.delegate = self
searchBar.placeholder = "Search here..."
// END SEARCHBAR
downloadJSON()
tableView.tableFooterView = UIView(frame: CGRect.zero)
}
// START SEARCHBAR
func error() {
labelError.textColor = UIColor.white
labelError.backgroundColor = UIColor.red
labelError.text = "no records found"
}
func ok() {
labelError.backgroundColor = UIColor.white
labelError.text = ""
}
// END SEARCHBAR
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if filteredArray.count != 0 {
ok()
return filteredArray.count
}
else {
error()
return filteredArray.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
cell.textLabel?.text = filteredArray[indexPath.row].data.children[1].data.author.capitalized
let view = UIView()
view.backgroundColor = UIColor.systemGray4
cell.selectedBackgroundView = view
if indexPath.row % 2 == 0 {
cell.backgroundColor = UIColor.systemGray6
}
else {
cell.backgroundColor = UIColor.white
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showDetails", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? DetailViewController {
destination.galleryDataDetail = filteredArray[(tableView.indexPathForSelectedRow?.row)!]
}
}
func downloadJSON() {
let url = URL(string: "\(baseURL)cat/top.json")
URLSession.shared.dataTask(with: url!) { [unowned self] (data, response, error) in
do {
self.dataArray = try JSONDecoder().decode([GalleryData].self, from: data!)
self.filteredArray = self.dataArray
}
catch {
print("Your TableView did not load data")
}
}.resume()
}
}
// START SEARCHBAR
extension ViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
guard
let searchText = searchBar.text
else {
return
}
if searchText == "" {
filteredArray = dataArray
return
}
filteredArray = dataArray.filter { $0.data.children[1].data.author.uppercased().contains(searchText.uppercased()) }
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.text = ""
downloadJSON()
tableView.reloadData()
}
}
// END SEARCHBAR