UITableView not displaying cells (using swift)

I am using xcode v6.4. I want to show all usernames I receive from AWS DynamoDB as a table. I tried the following code

import UIKit
class messagesTableViewController: UITableViewController {

var myData: Array<AnyObject> = []
override func viewDidLoad() {
    super.viewDidLoad()


    let exp = AWSDynamoDBScanExpression()

    //  exp.valueForKey("name")
    //    exp.scanFilter = [ "date" : cond ]

    self.scan(exp).continueWithSuccessBlock({ (task: AWSTask!) -> AWSTask! in
        NSLog("Scan multiple values - success")
        let results = task.result as! AWSDynamoDBPaginatedOutput
        for r in results.items {
            let myItem: Item = r as! Item

            println(myItem.name)
            self.myData.append(myItem.name)

            println("\(self.myData)")

        }
        return nil
    })
}

func scan(expression : AWSDynamoDBScanExpression) -> AWSTask! {

    let mapper = AWSDynamoDBObjectMapper.defaultDynamoDBObjectMapper()
    return mapper.scan(Item.self, expression: expression)
}

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

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete method implementation.
    // Return the number of rows in the section.
    println("\(myData.count)")
    return myData.count

}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cellID: String = "cell"
    var cell = tableView.dequeueReusableCellWithIdentifier(cellID) as! inboxTableViewCell
    dispatch_async(dispatch_get_main_queue(), {


        cell.nameLabel.text = self.myData[indexPath.row] as? String

    })



    return cell

}

      

Here, the print 'println ("(self.myData)")' command prints the correct data, but the same data is not displayed in a table.

Also, the same code works correctly and displays the cells in the table view when I add static values ​​to the array. For example, below is my code:

import UIKit

class messagesTableViewController: UITableViewController {


var myDummy: Array<AnyObject> = []

override func viewDidLoad() {
    super.viewDidLoad()

    var i = 1
    myDummy = ["Amit", "Kushal", "Saurabh", "Harsh", "Swar"]

 }   



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

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return myDummy.count

}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cellID: String = "cell"
    var cell = tableView.dequeueReusableCellWithIdentifier(cellID) as! inboxTableViewCell
    dispatch_async(dispatch_get_main_queue(), {


        cell.nameLabel.text = self.myDummy[indexPath.row] as? String

    })



    return cell

}

      

It will be a great help if someone can walk me through this.

+3


source to share


3 answers


I finally understood. Here's the updated code.

import UIKit

class messagesTableViewController: UITableViewController {

var myData: Array<AnyObject> = []


override func viewDidLoad() {
    super.viewDidLoad()

    var i = 1

    let exp = AWSDynamoDBScanExpression()

    //  exp.valueForKey("name")
    //    exp.scanFilter = [ "date" : cond ]

    self.scan(exp).continueWithSuccessBlock({ (task: AWSTask!) -> AWSTask! in
        NSLog("Scan multiple values - success")
        let results = task.result as! AWSDynamoDBPaginatedOutput
        for r in results.items {
            let myItem: Item = r as! Item

            println(myItem.name)
            self.myData.append(myItem.name)

            println("\(self.myData)")

        }

  // This is the change in code. It needs to be added because the AWS scan  gathers the data in a background queue and we need to get back to the main queue after the background task is completed and then reload the table view.
        dispatch_async(dispatch_get_main_queue(), {
            self.tableView.reloadData()
        });
        return nil
    })

}

func scan(expression : AWSDynamoDBScanExpression) -> AWSTask! {

    let mapper = AWSDynamoDBObjectMapper.defaultDynamoDBObjectMapper()
    return mapper.scan(Item.self, expression: expression)
}

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

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete method implementation.
    // Return the number of rows in the section.
    println("\(myData.count)")
    return myData.count

}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cellID: String = "cell"
    var cell = tableView.dequeueReusableCellWithIdentifier(cellID) as! inboxTableViewCell
    dispatch_async(dispatch_get_main_queue(), {


        cell.nameLabel.text = self.myData[indexPath.row] as? String

    })



    return cell

}



}

      



The code in the question doesn't work because the AWS scan is collecting data in the background and we need to go back to the main queue after the background task completes and then reload the table view.

+3


source


Here's the code that should work:



override func viewDidLoad() {
    super.viewDidLoad()
    let exp = AWSDynamoDBScanExpression()

    self.scan(exp).continueWithSuccessBlock({ (task: AWSTask!) -> AWSTask! in
    println("Scan multiple values - success")
    let results = task.result as! AWSDynamoDBPaginatedOutput
    for r in results.items {
        let myItem: Item = r as! Item

        println(myItem.name)
        self.myData.append(myItem.name)

     }
     // THIS IS THE CODE YOU NEED TO ADD:
     tableView.reloadSections(NSIndexSet(index: 0), withRowAnimation: UITableViewRowAnimation.Automatic) // Or choose some other animation.
     return nil
  })
}

      

0


source


Try removing the dispatch_async part and change the nameLabel to textLabel, for example:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCellWithIdentifier("cell") as! inboxTableViewCell


    cell.textLabel.text = self.myDummy[indexPath.row] as? String



    return cell

}

      

0


source







All Articles