I am attempting to parse data from a website and then display it into a tableview on the press of a button. I am using swift 3, Xcode 8.2 beta and can not get the data to store into an array or display into the tableView. Here is my tableViewCell class:
class TableViewCell: UITableViewCell {
@IBOutlet weak var userIdLabel: UILabel!
@IBOutlet weak var titleLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
Here is my viewController code:
import UIKit
class SecondViewController: UIViewController, UITableViewDelegate,UITableViewDataSource {
let urlString = "https://jsonplaceholder.typicode.com/albums"
@IBOutlet weak var tableView: UITableView!
var titleArray = [String]()
var userIdArray = [String]()
@IBAction func getDataButton(_ sender: Any) {
self.downloadJSONTask()
self.tableView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func downloadJSONTask() {
let url = NSURL(string: urlString)
var downloadTask = URLRequest(url: (url as? URL)!, cachePolicy: URLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 20)
downloadTask.httpMethod = "GET"
URLSession.shared.dataTask(with: (url! as URL), completionHandler: {(Data, URLResponse, Error) -> Void in
let jsonData = try? JSONSerialization.jsonObject(with: Data!, options: .allowFragments)
print(jsonData as Any)
if let albumArray = (jsonData! as AnyObject).value(forKey: "") as? NSArray {
for title in albumArray{
if let titleDict = title as? NSDictionary {
if let title = titleDict.value(forKey: "title") {
self.titleArray.append(title as! String)
print("title")
print(title)
}
if let title = titleDict.value(forKey: "userId") {
self.userIdArray.append(title as! String)
}
OperationQueue.main.addOperation ({
self.tableView.reloadData()
})
}
}
}
}).resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return titleArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell
cell.titleLabel.text = titleArray[indexPath.row]
cell.userIdLabel.text = userIdArray[indexPath.row]
return cell
}
}
There are many, many issues in your code, the worst is to use
NSArray/NSDictionary
in Swift.The JSON is an array of dictionaries, the value for key
title
isString
the value foruserID
isInt
, so you have to declare your arraysNever cast JSON data to most unspecified
Any
that's another no-go. Cast it always to the actual type. Another big problem is theData
parameter in the closure which clashes with the native struct inSwift3
. Use always lowercase parameter labels. The request is not used at all in your code. And in Swift 3 use always the native structsURL
,Data
,URLRequest
etc. Finally.allowFragments
is nonsense since the JSON starts clearly with a collection type.PS: Using two separate arrays as data source is horrible, too. Imagine that one of the optional bindings might fail and the number of items in the arrays will be different. That's a pretty invitation for a runtime crash.