我正在尝试从firebase检索数据并显示到多个按钮和标签中。 检索后我将其保存到字典中。 这是我的模特
import Foundation
import Firebase
class QuestionModel: NSObject {
var CorrectAnswer: String!
var Question: String!
var optionA: String!
var optionB: String!
var optionC: String!
init(snapshot: FIRDataSnapshot) {
if let snapshotDict = snapshot.value as? Dictionary<String, Any> {
CorrectAnswer = snapshotDict["CorrectAnswer"] as? String
Question = snapshotDict["Question"] as? String
optionA = snapshotDict["optionA"] as? String
optionB = snapshotDict["optionB"] as? String
optionC = snapshotDict["optionC"] as? String
}
}
}
我的JSON
我尝试了一些方法,但它返回 nil 。我认为是异步firebase的。
这是我的代码。
import Foundation
import UIKit
import Firebase
import FirebaseDatabase
class AnsweringQuestionViewController: UIViewController {
@IBOutlet weak var qLabel: UILabel!
@IBOutlet weak var buttonA: UIButton!
@IBOutlet weak var buttonB: UIButton!
@IBOutlet weak var buttonC: UIButton!
@IBOutlet weak var correctAnswer: UIButton!
//var buttons: [UIButton]! thinking of using button tags?
var ref: FIRDatabaseReference!
var questionModel : [QuestionModel] = []
override func viewDidLoad(){
super.viewDidLoad()
// FIRDatabase.database().persistenceEnabled = true
ref = FIRDatabase.database().reference()
db()
}
func db(){
ref.child("Science").observe(.value, with: {
snapshot in
for child in snapshot.children {
let user = QuestionModel.init(snapshot: (child as? FIRDataSnapshot)!)
self.questionModel.append(user)
}
self.qLabel.text = self.questionModel[0].Question
self.buttonA.setTitle("\(self.questionModel[0].CorrectAnswer)", for: UIControlState.normal)
}, withCancel: nil)
}
}
请光着我的代码,我还在学习。我不知道从哪里开始将数据显示到多个按钮并确定哪个按钮被“点击”是CorrectAnwer。
如果您想以更清洁的方式重构我的代码,我将非常高兴。谢谢:)
答案 0 :(得分:0)
试试这个......
import FirebaseDatabase
class Question {
var correctAnswer: String?
var question: String?
var optionA: String?
var optionB: String?
var optionC: String?
init(snapshot: FIRDataSnapshot){
if let snap = snapshot.value as? [String: String] {
correctAnswer = snap["CorrectAnswer"]
question = snap["Question"]
optionA = snap["OptionA"]
optionB = snap["OptionB"]
optionC = snap["OptionC"]
}
}
}
import FirebaseDatabase
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var qLabel: UILabel!
@IBOutlet weak var buttonA: UIButton!
@IBOutlet weak var buttonB: UIButton!
@IBOutlet weak var buttonC: UIButton!
@IBOutlet weak var correctAnswer: UIButton!
var fireRootRef: FIRDatabaseReference!
var questions = [Question]()
override func viewDidLoad() {
super.viewDidLoad()
fireRootRef = FIRDatabase.database().reference()
fetchQuestions(inCategory: "Science")
}
func fetchQuestions(inCategory category: String){
let questionsRef = fireRootRef.child(category)
questionsRef.observe(.value, with: {(snapshot)-> Void in
var allQuestions = [Question]()
for child in snapshot.children {
allQuestions.append(Question(snapshot: child as! FIRDataSnapshot))
}
self.questions = allQuestions
self.reloadUI(withQuestions: self.questions)
})
}
func reloadUI(withQuestions questions: [Question]){
guard questions.count > 0 else {return}
if let answerToQuestion1 = questions[0].correctAnswer, let wrongAnswer = questions[0].optionA, let wrongAnswer2 = questions[0].optionB, let wrongAnswer3 = questions[0].optionC {
let randomOrderedAnswers = [answerToQuestion1, wrongAnswer, wrongAnswer2, wrongAnswer3].shuffled()
buttonA.setTitle(randomOrderedAnswers[0], for: .normal)
buttonB.setTitle(randomOrderedAnswers[1], for: .normal)
buttonC.setTitle(randomOrderedAnswers[2], for: .normal)
correctAnswer.setTitle(randomOrderedAnswers[3], for: .normal)//keep in mind the correctAnswer label wont always contain the actual correct answer now
} else {
print("failed to get value for one of the answes options")
}
if let questionText = questions[0].question {
qLabel.text = questionText
} else {
qLabel.text = "failed to get question text"
}
}
}
extension MutableCollection where Indices.Iterator.Element == Index {
/// Shuffles the contents of this collection.
mutating func shuffle() {
let c = count
guard c > 1 else { return }
for (firstUnshuffled , unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1)) {
let d: IndexDistance = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
guard d != 0 else { continue }
let i = index(firstUnshuffled, offsetBy: d)
swap(&self[firstUnshuffled], &self[i])
}
}
}
extension Sequence {
/// Returns an array with the contents of this sequence, shuffled.
func shuffled() -> [Iterator.Element] {
var result = Array(self)
result.shuffle()
return result
}
}
<强>更新强> 我添加了扩展程序,允许您对数组中元素的顺序进行随机排列,以便您可以随机设置答案标签&#34;并且正确的答案永远不会在同一个地方。延期礼貌来自this question here
的@NateCook要知道是否选择了正确的答案,只需检查所选按钮的文本是否= =到问题的correctAnswer属性,例如if buttonA.title(for: .normal)! == questions[0].correctAnswer {print("correct answer selected)"}
。只需确保打开buttonA.title(for: .normal)
的可选值,否则它将包含单词&#34; optional&#34;在它之前,因此不会完全等于正确的答案文本