投票:投票登记两次
Voting: Vote registers twice
我正在做一个投票系统。但是,当您投赞成票然后取消投赞成票时,分数会上升一然后下降二。如果您随后尝试投反对票,则分数根本不会移动。我认为代码将删除赞成票记录为反对票,但我不确定为什么。转换您的投票会使比分达到预期的 2 分。除非您投赞成票,否则请留下 viewController,然后切换您的投票。这只会让您的投票改变 1 分。
@IBOutlet weak var checkbox: Checkbox!
@IBOutlet weak var downVote: Checkbox!
var boxcheck = false
var downcheck = false
var postRef:DatabaseReference{
return Database.database().reference().child("posts").child("comments")}
}
func set(comment:Comment) {
commentLabel.text = comment.text
upvoteCountLabel.text = String(comment.upvotes)
downcheck = UserDefaults.standard.bool(forKey: "\(comment.snap) downvotes")
boxcheck = UserDefaults.standard.bool(forKey: "\(comment.snap) upvotes")
downVote.isChecked = UserDefaults.standard.bool(forKey: "\(comment.snap) downvotes")
checkbox.isChecked = UserDefaults.standard.bool(forKey: "\(comment.snap) upvotes")
downcheck = UserDefaults.standard.bool(forKey: "\(comment.snap) downvotes")
boxcheck = UserDefaults.standard.bool(forKey: "\(comment.snap) upvotes")
func voteUp() {
self.postRef.child(comment.postID).child(comment.snap).child("upvotes").runTransactionBlock({ (currentData:MutableData) -> TransactionResult in
if (currentData.value as? [String: AnyObject]) == nil {
let upvotesNumber = comment.upvotes
var upvotes = upvotesNumber
upvotes += 1
currentData.value = upvotes
return TransactionResult.success(withValue: currentData)
}
//Abort like if there was a problem
print("abortion")
return TransactionResult.abort()
})
}
func voteDown(){
self.postRef.child(comment.postID).child(comment.snap).child("upvotes").runTransactionBlock({ (currentData:MutableData) -> TransactionResult in
if (currentData.value as? [String: AnyObject]) == nil {
let upvotesNumber = comment.upvotes
var upvotes = upvotesNumber
upvotes -= 1
currentData.value = upvotes
return TransactionResult.success(withValue: currentData)
}
//Abort like if there was a problem
print("abortion")
return TransactionResult.abort()
})
}
checkbox.valueChanged = { (value) in
print("checkbox value change: \(value)")
self.boxcheck = self.checkbox.isChecked
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
if self.checkbox.isChecked == true && self.downVote.isChecked == true{
voteUp()
self.boxcheck = self.checkbox.isChecked
}
if self.checkbox.isChecked == true && self.downVote.isChecked == false{
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
voteUp()
self.boxcheck = self.checkbox.isChecked
}
if self.checkbox.isChecked == false && self.downVote.isChecked == false{
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
voteDown()
self.downVote.isChecked = false
self.boxcheck = self.checkbox.isChecked
self.downcheck = self.downVote.isChecked
}
if self.checkbox.isChecked == false && self.downVote.isChecked == true{
voteDown()
self.boxcheck = self.checkbox.isChecked
}
if self.downVote.isChecked == true && self.checkbox.isChecked == true {
self.downVote.isChecked = false
self.downcheck = self.downVote.isChecked
}
print("POSTITIVE My current downcheck value is \(self.downcheck)")
print("POSITIVE My current upcheck value is \(self.boxcheck)")
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
}
downVote.valueChanged = { (value) in
self.downcheck = self.downVote.isChecked
print("downVote value change: \(value)")
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
if self.checkbox.isChecked == true && self.downVote.isChecked == true {
voteDown()
self.downcheck = self.downVote.isChecked
}
if self.checkbox.isChecked == false && self.downVote.isChecked == true {
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
voteDown()
self.downcheck = self.downVote.isChecked
}
if self.checkbox.isChecked == false && self.downVote.isChecked == false{
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
voteUp()
self.downcheck = self.downVote.isChecked
self.boxcheck = self.checkbox.isChecked
}
if self.checkbox.isChecked == true && self.downVote.isChecked == false {
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
voteUp()
self.downcheck = self.downVote.isChecked
}
if self.checkbox.isChecked == true && self.downVote.isChecked == true {
self.checkbox.isChecked = false
self.boxcheck = self.checkbox.isChecked
}
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
}
print("My current downcheck value is \(self.downcheck)")
print("My current upcheck value is \(self.boxcheck)")
}
}
Firebasse 引用工作正常,但如果您好奇,这里是我的 Comment 模型:
import Foundation
class Comment: Equatable {
static func == (lhs: Comment, rhs: Comment) -> Bool {
return lhs.id == rhs.id
}
var snap:String
var id:String
var text:String
var reports: Int
var upvotes: Int
var postID: String
init(id: String, text:String, reports:Int, snap: String, upvotes: Int, postID: String) {
self.id = id
self.text = text
self.reports = reports
self.snap = snap
self.upvotes = upvotes
self.postID = postID
}
还有 Firebase JSON:
{
"posts" : {
"-Lku3osQQXgagYMVI9ua" : {
"commentsNumber" : 2,
"reports" : 1,
"text" : "Hey",
"timestamp" : 1564342439656,
"title" : "Welcome to Librex",
"upvotes" : 1,
"userID" : "mMqFhoNiR3gWiTd7J4wtPABhtYB3"
}
"comments" : {
"-Lku3osQQXgagYMVI9ua" : {
"-LlcJ_6Kus1nuqaCk17R" : {
"comment_by_uid" : "N3HNT1aVkPXhiCRu9fzJknWYxCt2",
"comment_text" : "This is really cool; thanks!",
"reports" : 0,
"upvotes" : 3
},
"-Llhr2E7UodiuyvzeGMi" : {
"comment_by_uid" : "N3HNT1aVkPXhiCRu9fzJknWYxCt2",
"comment_text" : "K ",
"reports" : 0,
"upvotes" : 1
}
}
}
}
}
这是我用来投票的代码!
func voteUp() {
self.postRef.child(comment.postID).child(comment.snap).child("upvotes").runTransactionBlock({
(currentData: MutableData!) in
//value of the counter before an update
var value = currentData.value as? Int
//checking for nil data is very important when using
//transactional writes
if value == nil {
value = 0
}
//actual update
currentData.value = value! + 1
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
return TransactionResult.success(withValue: currentData)
}, andCompletionBlock: {
error, commited, snap in
//if the transaction was commited, i.e. the data
//under snap variable has the value of the counter after
//updates are done
if commited {
let upvotes = snap?.value as! Int
} else {
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
TransactionResult.abort()
}
})
}
func voteDown(){
self.postRef.child(comment.postID).child(comment.snap).child("upvotes").runTransactionBlock({
(currentData: MutableData!) in
//value of the counter before an update
var value = currentData.value as? Int
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
//checking for nil data is very important when using
//transactional writes
if value == nil {
value = 0
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
}
//actual update
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
currentData.value = value! - 1
return TransactionResult.success(withValue: currentData)
}, andCompletionBlock: {
error, commited, snap in
//if the transaction was commited, i.e. the data
//under snap variable has the value of the counter after
//updates are done
if commited {
let upvotes = snap?.value as! Int
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
} else {
TransactionResult.abort()
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
}
})
}
我正在做一个投票系统。但是,当您投赞成票然后取消投赞成票时,分数会上升一然后下降二。如果您随后尝试投反对票,则分数根本不会移动。我认为代码将删除赞成票记录为反对票,但我不确定为什么。转换您的投票会使比分达到预期的 2 分。除非您投赞成票,否则请留下 viewController,然后切换您的投票。这只会让您的投票改变 1 分。
@IBOutlet weak var checkbox: Checkbox!
@IBOutlet weak var downVote: Checkbox!
var boxcheck = false
var downcheck = false
var postRef:DatabaseReference{
return Database.database().reference().child("posts").child("comments")}
}
func set(comment:Comment) {
commentLabel.text = comment.text
upvoteCountLabel.text = String(comment.upvotes)
downcheck = UserDefaults.standard.bool(forKey: "\(comment.snap) downvotes")
boxcheck = UserDefaults.standard.bool(forKey: "\(comment.snap) upvotes")
downVote.isChecked = UserDefaults.standard.bool(forKey: "\(comment.snap) downvotes")
checkbox.isChecked = UserDefaults.standard.bool(forKey: "\(comment.snap) upvotes")
downcheck = UserDefaults.standard.bool(forKey: "\(comment.snap) downvotes")
boxcheck = UserDefaults.standard.bool(forKey: "\(comment.snap) upvotes")
func voteUp() {
self.postRef.child(comment.postID).child(comment.snap).child("upvotes").runTransactionBlock({ (currentData:MutableData) -> TransactionResult in
if (currentData.value as? [String: AnyObject]) == nil {
let upvotesNumber = comment.upvotes
var upvotes = upvotesNumber
upvotes += 1
currentData.value = upvotes
return TransactionResult.success(withValue: currentData)
}
//Abort like if there was a problem
print("abortion")
return TransactionResult.abort()
})
}
func voteDown(){
self.postRef.child(comment.postID).child(comment.snap).child("upvotes").runTransactionBlock({ (currentData:MutableData) -> TransactionResult in
if (currentData.value as? [String: AnyObject]) == nil {
let upvotesNumber = comment.upvotes
var upvotes = upvotesNumber
upvotes -= 1
currentData.value = upvotes
return TransactionResult.success(withValue: currentData)
}
//Abort like if there was a problem
print("abortion")
return TransactionResult.abort()
})
}
checkbox.valueChanged = { (value) in
print("checkbox value change: \(value)")
self.boxcheck = self.checkbox.isChecked
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
if self.checkbox.isChecked == true && self.downVote.isChecked == true{
voteUp()
self.boxcheck = self.checkbox.isChecked
}
if self.checkbox.isChecked == true && self.downVote.isChecked == false{
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
voteUp()
self.boxcheck = self.checkbox.isChecked
}
if self.checkbox.isChecked == false && self.downVote.isChecked == false{
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
voteDown()
self.downVote.isChecked = false
self.boxcheck = self.checkbox.isChecked
self.downcheck = self.downVote.isChecked
}
if self.checkbox.isChecked == false && self.downVote.isChecked == true{
voteDown()
self.boxcheck = self.checkbox.isChecked
}
if self.downVote.isChecked == true && self.checkbox.isChecked == true {
self.downVote.isChecked = false
self.downcheck = self.downVote.isChecked
}
print("POSTITIVE My current downcheck value is \(self.downcheck)")
print("POSITIVE My current upcheck value is \(self.boxcheck)")
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
}
downVote.valueChanged = { (value) in
self.downcheck = self.downVote.isChecked
print("downVote value change: \(value)")
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
if self.checkbox.isChecked == true && self.downVote.isChecked == true {
voteDown()
self.downcheck = self.downVote.isChecked
}
if self.checkbox.isChecked == false && self.downVote.isChecked == true {
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
voteDown()
self.downcheck = self.downVote.isChecked
}
if self.checkbox.isChecked == false && self.downVote.isChecked == false{
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
voteUp()
self.downcheck = self.downVote.isChecked
self.boxcheck = self.checkbox.isChecked
}
if self.checkbox.isChecked == true && self.downVote.isChecked == false {
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
voteUp()
self.downcheck = self.downVote.isChecked
}
if self.checkbox.isChecked == true && self.downVote.isChecked == true {
self.checkbox.isChecked = false
self.boxcheck = self.checkbox.isChecked
}
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
}
print("My current downcheck value is \(self.downcheck)")
print("My current upcheck value is \(self.boxcheck)")
}
}
Firebasse 引用工作正常,但如果您好奇,这里是我的 Comment 模型:
import Foundation
class Comment: Equatable {
static func == (lhs: Comment, rhs: Comment) -> Bool {
return lhs.id == rhs.id
}
var snap:String
var id:String
var text:String
var reports: Int
var upvotes: Int
var postID: String
init(id: String, text:String, reports:Int, snap: String, upvotes: Int, postID: String) {
self.id = id
self.text = text
self.reports = reports
self.snap = snap
self.upvotes = upvotes
self.postID = postID
}
还有 Firebase JSON:
{
"posts" : {
"-Lku3osQQXgagYMVI9ua" : {
"commentsNumber" : 2,
"reports" : 1,
"text" : "Hey",
"timestamp" : 1564342439656,
"title" : "Welcome to Librex",
"upvotes" : 1,
"userID" : "mMqFhoNiR3gWiTd7J4wtPABhtYB3"
}
"comments" : {
"-Lku3osQQXgagYMVI9ua" : {
"-LlcJ_6Kus1nuqaCk17R" : {
"comment_by_uid" : "N3HNT1aVkPXhiCRu9fzJknWYxCt2",
"comment_text" : "This is really cool; thanks!",
"reports" : 0,
"upvotes" : 3
},
"-Llhr2E7UodiuyvzeGMi" : {
"comment_by_uid" : "N3HNT1aVkPXhiCRu9fzJknWYxCt2",
"comment_text" : "K ",
"reports" : 0,
"upvotes" : 1
}
}
}
}
}
这是我用来投票的代码!
func voteUp() {
self.postRef.child(comment.postID).child(comment.snap).child("upvotes").runTransactionBlock({
(currentData: MutableData!) in
//value of the counter before an update
var value = currentData.value as? Int
//checking for nil data is very important when using
//transactional writes
if value == nil {
value = 0
}
//actual update
currentData.value = value! + 1
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
return TransactionResult.success(withValue: currentData)
}, andCompletionBlock: {
error, commited, snap in
//if the transaction was commited, i.e. the data
//under snap variable has the value of the counter after
//updates are done
if commited {
let upvotes = snap?.value as! Int
} else {
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
TransactionResult.abort()
}
})
}
func voteDown(){
self.postRef.child(comment.postID).child(comment.snap).child("upvotes").runTransactionBlock({
(currentData: MutableData!) in
//value of the counter before an update
var value = currentData.value as? Int
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
//checking for nil data is very important when using
//transactional writes
if value == nil {
value = 0
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
}
//actual update
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
currentData.value = value! - 1
return TransactionResult.success(withValue: currentData)
}, andCompletionBlock: {
error, commited, snap in
//if the transaction was commited, i.e. the data
//under snap variable has the value of the counter after
//updates are done
if commited {
let upvotes = snap?.value as! Int
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
} else {
TransactionResult.abort()
UserDefaults.standard.set(self.checkbox.isChecked, forKey: "\(comment.snap) upvotes")
UserDefaults.standard.set(self.downVote.isChecked, forKey: "\(comment.snap) downvotes")
}
})
}