Reputation: 285
I am using xcode v6.4. I want to display all the names of the users that I get from AWS DynamoDB in to a table view. 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 command 'println("(self.myData)")' prints the proper data but the same data does not get displayed on the table view.
Also, the same code works properly and displays the cells in table view when I add static values to an 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 somebody can guide me through this.
Upvotes: 3
Views: 4353
Reputation: 285
I figured it out finally. Here is 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 did not work because 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.
Upvotes: 3
Reputation:
Try removing the dispatch_async part and change nameLabel to textLabel, like this:
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
}
Upvotes: 0
Reputation: 997
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
})
}
Upvotes: 0