我试图查询数据从firebase内的for循环,我的问题是,因为查询需要时间来连接,swift跳过查询,回来以后做他们。这就产生了一个问题,我的循环计数器正在滴答滴答,但查询被保存到以后,当查询最终执行时,计数器变量全部out of wack。
代码被跳过的地方是在查询之后,在那里我试图追加到一个数组。
func getSelectedData() {
var exerciseIndex = 0
for i in 0...Master.exercises.count - 1 {
if Master.exercises[i].name == self.exerciseName {
exerciseIndex = i
}
}
let numOfSets = Master.exercises[exerciseIndex].totalSets
// For each date record
for count in 0...self.returnedExercises.count-1 {
// Creates a new dataSet
dataSet.append(dataSetStruct())
dataSet[count].date = returnedExercises[count]
for number in 0...(numOfSets - 1) {
// Retrives the reps
let repsDbCallHistory = db.collection("users").document("(userId)").collection("ExerciseData").document("AllExercises").collection(exerciseName).document(returnedExercises[count]).collection("Set(number + 1)").document("reps")
repsDbCallHistory.getDocument { (document, error) in
if let document = document, document.exists {
// For every document (Set) in the database, copy the values and add them to the array
let data:[String:Any] = document.data()!
self.dataSet[count].repsArray.append(data["Reps(number + 1)"] as! Int)
}
else {
// error
}
}
//Retrives the weights
let weightsDbCallHistory = db.collection("users").document("(userId)").collection("ExerciseData").document("AllExercises").collection(exerciseName).document(returnedExercises[count]).collection("Set(number + 1)").document("weights")
weightsDbCallHistory.getDocument { (document, error) in
if let document = document, document.exists {
// For every document (Set) in the database, copy the values and add them to the array
let data:[String:Any] = document.data()!
self.dataSet[count].weightsArray.append(data["Weight(number + 1)"] as! Float)
self.updateGraph()
}
else {
// error
}
}
}
}
}
我甚至尝试将查询分解为另一个函数,但这似乎并没有解决问题。
感谢您的帮助。
编辑:
func getSelectedData() {
if returnedExercises.count > 0 {
// Create a dispatch group
let group = DispatchGroup()
print("Getting Data")
// For each date record
for count in 0...self.returnedExercises.count-1 {
// Creates a new dataSet
self.dataSet.append(dataSetStruct())
self.dataSet[count].date = self.returnedExercises[count]
for number in 0...(self.numOfSets - 1) {
print("At record (count), set (number)")
// Enter the group
group.enter()
// Start the dispatch
DispatchQueue.global().async {
// Retrives the reps
let repsDbCallHistory = self.db.collection("users").document("(self.userId)").collection("ExerciseData").document("AllExercises").collection(self.exerciseName).document(self.returnedExercises[count]).collection("Set(number + 1)").document("reps")
repsDbCallHistory.getDocument { (document, error) in
if let document = document, document.exists {
// For every document (Set) in the database, copy the values and add them to the array
let data:[String:Any] = document.data()!
self.dataSet[count].repsArray.append(data["Reps(number + 1)"] as! Int)
print("Getting data: (number)")
group.leave()
}
else {
// error
}
}
}
group.wait()
print("Finished getting data")
}
}
我现在尝试简化函数,并且在函数中只有一个数据库调用来尝试调度组。我不知道为什么firebase这样做,但代码从未执行组。如果离开,程序就会闲置。如果我做错了什么请告诉我,谢谢。
这是打印语句显示的内容:
获取数据
在记录0处,设置0
在记录0处,设置1
在记录0处,设置2
在记录1处,设置0
在记录1处,设置1
在记录1处,设置2
print("Getting data: (number)")由于某些原因从未被执行。
我认为也许firebase调用在一个单独的线程或其他东西上运行,这也会使它们暂停执行,但这只是我的理论
EDIT2::
func getOneRepMax(completion: @escaping (_ message: String) -> Void) {
if returnedOneRepMax.count > 0 {
print("Getting Data")
// For each date record
for count in 0...self.returnedOneRepMax.count-1 {
// Creates a new dataSet
oneRPDataSet.append(oneRepMaxStruct())
oneRPDataSet[count].date = returnedOneRepMax[count]
// Retrives the reps
let oneRepMax = db.collection("users").document("(userId)").collection("UserInputData").document("OneRepMax").collection(exerciseName).document(returnedOneRepMax[count])
oneRepMax.getDocument { (document, error) in
if let document = document, document.exists {
// For every document (Set) in the database, copy the values and add them to the array
let data:[String:Any] = document.data()!
self.oneRPDataSet[count].weight = Float(data["Weight"] as! String)!
print("Getting data: (count)")
completion("DONE")
self.updateGraph()
}
else {
// error
}
}
}
}
}
我尝试使用完成处理程序的不同的功能,它也不能正常工作。
self.getOneRepMax(completion: { message in
print(message)
})
print("Finished getting data")
打印语句的顺序:
获取数据
获取数据:0
完成
获取数据:1
完成
完成获取数据
当前打印语句输出的顺序:
正在获取数据
已完成获取数据
正在获取数据:1
已完成
正在获取数据:0
已完成
我甚至不确定计数是怎么可能的,因为我的for循环计数向上,我犯了什么错误?
我认为你需要的是调度组。
let dispatchGroup1 = DispatchGroup()
let dispatchGroup2 = DispatchGroup()
dispatchGroup1.enter()
firebaseRequest1() { (_, _) in
doThings()
dispatchGroup1.leave()
}
dispatchGroup2.enter()
dispatchGroup1.notify(queue: .main) {
firebaseRequest2() { (_, _ ) in
doThings()
dispatchGroup2.leave()
}
dispatchGroup2.notify(queue: .main) {
completionHandler()
}