如何在单个函数中执行两个完成块并将完成块的数据传递给下一个视图控制器?
How to execute two completion blocks in a single function and pass the data of the completion block to next view controller?
这是我的数据库结构:
我正在使用带闭包的函数,执行两个完成块并将数据存储在两个单独的数组中。获得数据后,我想将数据传递给下一个视图控制器到不同的变量中,但我得到的是两个数组的相同值。
@IBAction func GoToAnswerPage(_ sender: Any) {
self.getData(refe:JoinCodeTextField.text!) { (array) in
self.performSegue(withIdentifier:"JoinToAnswerPage",sender:array)
}
}
func getData(refe: String, completion: @escaping (([Any]) -> ())) {
var questionArray = [Any]()
var answerArray = [Any]()
let ref = Database.database().reference(fromURL: "https://pollapp-30419.firebaseio.com/").child("Questions/\(refe)/")
ref.child("Question_And_Options").observeSingleEvent(of: .value,with: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? DataSnapshot, let value = rest.value{
questionArray.append(value)
}
completion(questionArray)
})
ref.child("Answer_Key").observeSingleEvent(of: .value,with: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? DataSnapshot, let value = rest.value{
answerArray.append(value)
}
completion(answerArray)
})
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let joinViewController = segue.destination as? JoinAnswerViewController
else {
return
}
joinViewController.answers = sender as! [String]
joinViewController.options = sender as! [String]
}
在下一个视图控制器上。
var options = [Any]()
var answers = [Any]()
这是我得到的输出:
answers-["Test Q-1", "Test A-1", "Test A-2"]
questions-["Test Q-1", "Test A-1", "Test A-2"]
answers-["Test A-1"]
questions-["Test A-1"]
相反,我应该得到:
questions-["Test Q-1", "Test A-1", "Test A-2"]
answers-["Test A-1"]
您的完成处理程序将被调用两次,一次针对 "answers",一次针对 "questions"。它们可以按任意顺序出现,因此您应该在完成时额外传递一个 type
以了解您收到了哪个。使用 [String : [Any]]
字典收集两个数组,并在收到两个数组并将它们存储在字典 arrays
.
中时调用 self.performSegue(withIdentifier:sender:)
在 prepare(for:sender:)
中解压缩 sender
字典并分配值:
@IBAction func GoToAnswerPage(_ sender: Any) {
var arrays = [String : [Any]]()
self.getData(refe: JoinCodeTextField.text!) { (array, type) in
arrays[type] = array
if arrays.count == 2 {
self.performSegue(withIdentifier:"JoinToAnswerPage",sender: arrays)
}
}
}
func getData(refe: String, completion: @escaping (([Any], String) -> ())) {
var questionArray = [Any]()
var answerArray = [Any]()
let ref = Database.database().reference(fromURL: "https://pollapp-30419.firebaseio.com/").child("Questions/\(refe)/")
ref.child("Question_And_Options").observeSingleEvent(of: .value,with: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? DataSnapshot, let value = rest.value{
questionArray.append(value)
}
completion(questionArray, "question")
})
ref.child("Answer_Key").observeSingleEvent(of: .value,with: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? DataSnapshot, let value = rest.value{
answerArray.append(value)
}
completion(answerArray, "answer")
})
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let joinViewController = segue.destination as? JoinAnswerViewController
else {
return
}
guard let arrays = sender as? [String : [Any]],
let answers = arrays["answer"] as? [String],
let questions = arrays["question"] as? [String]
else { return }
joinViewController.answers = answers
joinViewController.options = questions
}
注意:当用户按下按钮时,他们应该立即得到响应。由于您是从网络加载数据,因此可能会有延迟,使用户怀疑是否发生了什么。最好将 JoinCodeTextField.text!
传递给 JoinAnswerViewController
并让它加载 question/answer 数据。 JoinAnswerViewController
可以在数据加载时显示 UIActivityIndicatorView
(微调器),让用户知道数据即将到来。拥有两个数组后,您可以设置 JoinAnswerViewController
.
这是我的数据库结构:
我正在使用带闭包的函数,执行两个完成块并将数据存储在两个单独的数组中。获得数据后,我想将数据传递给下一个视图控制器到不同的变量中,但我得到的是两个数组的相同值。
@IBAction func GoToAnswerPage(_ sender: Any) {
self.getData(refe:JoinCodeTextField.text!) { (array) in
self.performSegue(withIdentifier:"JoinToAnswerPage",sender:array)
}
}
func getData(refe: String, completion: @escaping (([Any]) -> ())) {
var questionArray = [Any]()
var answerArray = [Any]()
let ref = Database.database().reference(fromURL: "https://pollapp-30419.firebaseio.com/").child("Questions/\(refe)/")
ref.child("Question_And_Options").observeSingleEvent(of: .value,with: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? DataSnapshot, let value = rest.value{
questionArray.append(value)
}
completion(questionArray)
})
ref.child("Answer_Key").observeSingleEvent(of: .value,with: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? DataSnapshot, let value = rest.value{
answerArray.append(value)
}
completion(answerArray)
})
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let joinViewController = segue.destination as? JoinAnswerViewController
else {
return
}
joinViewController.answers = sender as! [String]
joinViewController.options = sender as! [String]
}
在下一个视图控制器上。
var options = [Any]()
var answers = [Any]()
这是我得到的输出:
answers-["Test Q-1", "Test A-1", "Test A-2"]
questions-["Test Q-1", "Test A-1", "Test A-2"]
answers-["Test A-1"]
questions-["Test A-1"]
相反,我应该得到:
questions-["Test Q-1", "Test A-1", "Test A-2"]
answers-["Test A-1"]
您的完成处理程序将被调用两次,一次针对 "answers",一次针对 "questions"。它们可以按任意顺序出现,因此您应该在完成时额外传递一个 type
以了解您收到了哪个。使用 [String : [Any]]
字典收集两个数组,并在收到两个数组并将它们存储在字典 arrays
.
self.performSegue(withIdentifier:sender:)
在 prepare(for:sender:)
中解压缩 sender
字典并分配值:
@IBAction func GoToAnswerPage(_ sender: Any) {
var arrays = [String : [Any]]()
self.getData(refe: JoinCodeTextField.text!) { (array, type) in
arrays[type] = array
if arrays.count == 2 {
self.performSegue(withIdentifier:"JoinToAnswerPage",sender: arrays)
}
}
}
func getData(refe: String, completion: @escaping (([Any], String) -> ())) {
var questionArray = [Any]()
var answerArray = [Any]()
let ref = Database.database().reference(fromURL: "https://pollapp-30419.firebaseio.com/").child("Questions/\(refe)/")
ref.child("Question_And_Options").observeSingleEvent(of: .value,with: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? DataSnapshot, let value = rest.value{
questionArray.append(value)
}
completion(questionArray, "question")
})
ref.child("Answer_Key").observeSingleEvent(of: .value,with: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? DataSnapshot, let value = rest.value{
answerArray.append(value)
}
completion(answerArray, "answer")
})
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let joinViewController = segue.destination as? JoinAnswerViewController
else {
return
}
guard let arrays = sender as? [String : [Any]],
let answers = arrays["answer"] as? [String],
let questions = arrays["question"] as? [String]
else { return }
joinViewController.answers = answers
joinViewController.options = questions
}
注意:当用户按下按钮时,他们应该立即得到响应。由于您是从网络加载数据,因此可能会有延迟,使用户怀疑是否发生了什么。最好将 JoinCodeTextField.text!
传递给 JoinAnswerViewController
并让它加载 question/answer 数据。 JoinAnswerViewController
可以在数据加载时显示 UIActivityIndicatorView
(微调器),让用户知道数据即将到来。拥有两个数组后,您可以设置 JoinAnswerViewController
.