【发布时间】:2019-08-15 09:40:25
【问题描述】:
我正在制作一个投票系统。但是,当您投票然后删除投票时,分数会上升 1,然后下降 2。如果您随后尝试投反对票,则分数根本不会移动。我认为代码将删除赞成票记录为反对票,但我不知道为什么。切换您的投票会使预期的 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 引用工作正常,但如果您好奇,这是我的评论模型:
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
}
}
}
}
}
【问题讨论】:
-
为什么要检查 currentData 是否为 nil?
if (currentData.value as? [String: AnyObject]) == nil。在访问它之前,您应该检查以确保它不是 nil。见Save Data As Transaction -
嗯...当我将其更改为
if (currentData.value as? [String: AnyObject]) == nil时,没有投票通过。我通过阅读文档获得了此代码。我相信你,但我不确定发生了什么 -
除非我忽略了某些东西,否则这种逻辑是没有意义的。整个想法是您要验证
currentData.value不为零,以便您可以对其进行读写。如果为 nil,则应用程序将崩溃。我不确定您在文档中的何处看到该代码 - 如果您查看我对文档的评论中的链接,您可以清楚地看到在使用它之前是否检查了不是 nil;if var post = currentData.value as? [String : AnyObject],另外,你评论中的代码和我指出的一样,所以你没有做任何改变。 -
对不起,我的意思是
if (currentData.value as? [String: AnyObject]) != nil {使代码不更新值。于是我取出了 if 语句,然后打印了currentData.value是什么,得到了 Optional(0) -
您的代码正在执行以下操作;如果 currentData.value 为 nil,表示节点不存在,则写入一些数据。如果存在,什么也不做。这也意味着如果该节点以前不存在,则将创建该节点,并将其值设置为 comment.upvotes。因此,您认为代码在做什么,并不是它实际上在做的事情,这可能就是您没有得到预期结果的原因。
标签: ios swift firebase firebase-realtime-database voting