如何在继续swift之前强制执行firebase函数



我试图查询数据从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()
}

最新更新