So I'm making a news feed similar to the one in Yik Yak in which users post content, and other users can upvote or downvote that post. I'm integrating this function with Parse, and I've successfully made upvoting and downvoting functions that upload to Parse (following the tutorial here: http://shrikar.com/parse-backed-uitableview-in-ios-8-build-yik-yak-clone-part-2/). Unfortunately I'm struggling to figure out how to allow a user to only upvote/downvote once.
My initial idea was to create locally stored Booleans for if the user has upvoted or downvoting, and use if/else statements to determine if the user can upvote/downvote again. This has lead me to the following code (IBActions connected to the buttons for upvoting and downvoting):
class TableViewController: PFQueryTableViewController {
var hasUpvoted: Bool?
var hasDownvoted: Bool?
@IBAction func yellUpvote(sender: AnyObject) {
let hitPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let hitIndex = self.tableView.indexPathForRowAtPoint(hitPoint)
let object = objectAtIndexPath(hitIndex)
object!.incrementKey("voteCount")
object!.saveInBackground()
self.tableView.reloadData()
NSLog("Top Index Path \(hitIndex?.row)")
if (hasUpvoted == true) {
println("Do nothing, A")
}
if (hasUpvoted == false) {
if (hasDownvoted == true){
println("Add two points, B")
hasUpvoted = true
hasDownvoted = false
}
}
if (hasUpvoted == nil){
if (hasDownvoted == true){
println("Add 2 pts, E")
hasUpvoted = true
hasDownvoted = false
}
if (hasDownvoted == nil){
println("Add 1 point, G")
hasUpvoted = true
}
}
}
@IBAction func yellDownvote(sender: AnyObject) {
let hitPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let hitIndex = self.tableView.indexPathForRowAtPoint(hitPoint)
let object = objectAtIndexPath(hitIndex)
object!.incrementKey("voteCount", byAmount: -1)
object!.saveInBackground()
self.tableView.reloadData()
NSLog("Bottom Index Path \(hitIndex?.row)")
if (hasDownvoted == true) {
println("do nothing, H")
}
if (hasDownvoted == false) {
if (hasUpvoted == true){
println("downvote 2, J")
hasDownvoted = true
hasUpvoted = false
}
}
if (hasDownvoted == nil){
if (hasUpvoted == true){
println ("downvote 2, L")
hasDownvoted = true
hasUpvoted = false
}
if (hasUpvoted == nil) {
println ("downvote 1, N")
hasDownvoted = true
hasUpvoted = false
}
}
}
As I quickly realized, these Booleans are not exclusive to the given cell in the TableView, so if I upvoted post A, and wanted to upvote post B, the Booleans would be set as if I'd already upvoted post B. The second issue is that these would be reset to nil upon a user closing the app, allowing them to vote multiple times on the same post.
My next thought was to use the following code to make the Booleans exclusive to the given cell:
let hitPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let hitIndex = self.tableView.indexPathForRowAtPoint(hitPoint)
I can't figure out how to do this though. Further, this wouldn't solve the issue of the user being able to simply close the app in order to regain the ability to vote again.
So, does anyone have a solution as to how to allow a user to only vote once?