virat virat - 4 months ago 29
Swift Question

Populate the tableView with JSON data

Here i am trying to load the table view with JSON data but data is not showing up. I don't know where the problem is i think i am not getting data into array properly.Tried a lot but not getting what i am doing wrong.New to iOS.

Below is my JSON data:


{"total_images_count":266,"datetime_value":"2016-07-15
19:28:37","total_count_response":"","image_path":"http://www.expert.com/test/images/","task":[{"image_name":"file1","image_path":"1461468362622.jpg"},{"image_name":"file2","image_path":"1461468362622.jpg"},


class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

var arrDict :NSMutableArray = NSMutableArray()

override func viewDidLoad() {

super.viewDidLoad()

jsonParsingFromURL()

}

func jsonParsingFromURL () {
let url = NSURL(string: "http://clipbyte.com/ontest/cron/webapi.php?task=webapi.getAllClips")

let request = NSURLRequest(URL: url!)

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
self.startParsing(data!)
}
}

func startParsing(data :NSData)
{
let dict: NSDictionary!=(try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers)) as! NSDictionary
for var i = 0 ; i < (dict.valueForKey("task") as! NSArray).count ; i++
{
arrDict.addObject((dict.valueForKey("task") as! NSArray) .objectAtIndex(i))
}

NSLog("array is ", arrDict)
}


func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return arrDict.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{

let cell : UITableViewCell! = tableView.dequeueReusableCellWithIdentifier("Cell")

let strTitle : NSString=arrDict[indexPath.row] .valueForKey("clip_name") as! NSString

cell.textLabel!.text=strTitle as String
cell.imageView?.image = arrDict[indexPath.row].valueForKey("clip_image_path") as? UIImage
return cell

}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}


}


if i use the below class for custom cell it gives me error at init function below IBOutlet

TableViewCell class

class TableViewCell: UITableViewCell
{
@IBOutlet weak var lblTitle: UILabel!
@IBOutlet weak var lbDetails: UILabel!

init(style: UITableViewCellStyle, reuseIdentifier: String) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// Initialization code
}
override func awakeFromNib() {
super.awakeFromNib()

// Initialization code
}

override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}

Answer

Write a function to run a closure on main thread:

typealias Closure = () -> Void
func runOnMain(closure: Closure) {
    dispatch_async(dispatch_get_main_queue(), {
        () -> Void in
        closure()
    })
}

Then in your method startParsing

Finish by reloading tableView:

func startParsing(data :NSData)
{
    let dict: NSDictionary!=(try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers)) as! NSDictionary
    for var i = 0 ; i < (dict.valueForKey("task") as! NSArray).count ; i++
    {
        arrDict.addObject((dict.valueForKey("task") as! NSArray) .objectAtIndex(i))
    }

    NSLog("array is ", arrDict)
    runOnMain {
        self.tableView.reloadData()
    }
}

Edit: A tip is to create a Macros.swift file without any class and put the runOnMain method and typealias in that file. That way that method is accessible from anywhere in your project.

Also you should really create Models from your JSON. I suggest you take a look at my open source project which fetches data using Alamofire and parses the JSON into models.

Comments