Swift 如何在for循环之外执行代码(需要等待循环从Firebase数据库检索完数据)?
我试图显示一个表视图,它按汽车旅行时间显示机构Swift 如何在for循环之外执行代码(需要等待循环从Firebase数据库检索完数据)?,swift,for-loop,firebase-realtime-database,mkdirection,Swift,For Loop,Firebase Realtime Database,Mkdirection,我试图显示一个表视图,它按汽车旅行时间显示机构 查询循环通过数据库中的学校列表来检索它们的坐标 计算距用户当前位置的距离 如果距离小于20英里,则使用MKDirections()计算eta时间 计算eta时间后,将相关信息附加到表视图的数组中,按eta时间对数组进行排序,只保留前10个 这里的问题是,在用户当前位置的20英里范围内通常有许多机构,MKDirections()限制了您在给定时间范围内计算eta时间的请求量。因此,我的表视图常常无法显示eta时间 对我来说,最明显的解决方案是在计算e
let schoolDB = Database.database().reference().child("Schools")
schoolDB.observe(.value, with: { (snapshot) in
self.subjectTimesArray.removeAll()
for child in snapshot.children {
let schoolSnapshot = child as! DataSnapshot
let approvalString = schoolSnapshot.childSnapshot(forPath: "Approved").value as! String
if approvalString == "Yes" {
let schoolID = schoolSnapshot.key
let schoolName = schoolSnapshot.childSnapshot(forPath: "Name").value as! String
let schoolLatitude = schoolSnapshot.childSnapshot(forPath: "Latitude").value as! Double
let schoolLongitude = schoolSnapshot.childSnapshot(forPath: "Longitude").value as! Double
let schoolLocation = CLLocation(latitude: schoolLatitude, longitude: schoolLongitude)
let distance = schoolLocation.distance(from: self.userLocation) / 1600
if distance < 20 {
let subjectDB = Database.database().reference().child("Subject/" + schoolID + "/" + date)
subjectDB.observeSingleEvent(of: .value, with: { (subjectSnapshot) in
let startTime = subjectSnapshot.childSnapshot(forPath: "Maths/Start").value as! String
let userPlacemark = MKMapItem(placemark: MKPlacemark(coordinate: userLocation.coordinate))
let schoolPlacemark = MKMapItem(placemark: MKPlacemark(coordinate: schoolLocation.coordinate))
let directionsRequest = MKDirections.Request()
directionsRequest.source = userPlacemark
directionsRequest.destination = schoolPlacemark
directionsRequest.requestsAlternateRoutes = false
directionsRequest.transportType = .automobile
let directions = MKDirections(request: directionsRequest)
directions.calculateETA(completionHandler: { (response, error) in
if let seconds = response?.expectedTravelTime {
let minutes = seconds / 60
self.subjectTimesArray.append(.init(schoolID: schoolID, schoolName: schoolName, distance: distance, eta: Int(minutes), subjectStart: startTime))
}
self.subjectTimesArray.sort(by: {$0.eta < $1.eta})
if self.subjectTimesArray.count > 10 {
self.subjectTimesArray.removeLast(self.subjectTimesArray.count - 10)
}
self.subjectTimesTableView.reloadData()
})
})
}
}
}
})
让schoolDB=Database.Database().reference().child(“学校”)
schoolDB.observe(.value,其中:{(快照)位于
self.subjectTimesArray.removeAll()
对于snapshot.children中的子对象{
让schoolSnapshot=child as!DataSnapshot
让approvalString=schoolSnapshot.childSnapshot(forPath:“Approved”)。值为!字符串
如果approvalString==“是”{
让schoolID=schoolSnapshot.key
让schoolName=schoolsapshot.childSnapshot(forPath:“Name”)。值为!字符串
让schoolLatitude=schoolSnapshot.childSnapshot(forPath:“Latitude”)。值为!Double
让SchoolLength=schoolSnapshot.childSnapshot(forPath:“经度”)。值为!Double
let schoolLocation=CLLocation(纬度:学校纬度,经度:学校经度)
让距离=学校位置。距离(from:self.userLocation)/1600
如果距离<20{
让subjectDB=Database.Database().reference().child(“Subject/”+schoolID+“/”+date)
subjectDB.ObservesingEvent(of:.值,其中:{(subjectSnapshot))位于
让startTime=subjectSnapshot.childSnapshot(forPath:“数学/开始”)。值为!字符串
让userPlacemark=MKMapItem(placemark:MKPlacemark(坐标:userLocation.coordinate))
让schoolPlacemark=MKMapItem(placemark:MKPlacemark(坐标:schoolLocation.coordinate))
let directionrequest=MKDirections.Request()
DirectionRequest.source=userPlacemark
DirectionRequest.destination=学校地点标记
DirectionRequest.RequestSalterRoutes=false
DirectionRequest.transportType=.automobile
let directions=MKDirections(请求:directionrequest)
completionHandler:{(响应,错误)在
如果let seconds=响应?.expectedTravelTime{
让分钟=秒/60
self.subjectTimeArray.append(.init(schoolID:schoolID,schoolName:schoolName,distance:distance,eta:Int(分钟),subjectStart:startTime))
}
self.subjectTimesArray.sort(按:{$0.eta<$1.eta})
如果self.subjectTimesArray.count>10{
self.subjectTimesArray.removeLast(self.subjectTimesArray.count-10)
}
self.subjectTimesTableView.reloadData()
})
})
}
}
}
})
您可以创建一个函数,该函数使用一个参数作为学校来计算距离,并在距离小于20英里时调用该函数;或者,如果距离小于20英里,则将数据库中的每个学校附加到一个新数组中,并根据该数组进行计算。如果您选择第二个选项,它将只在20英里以下的学校中循环,我建议您选择第一个选项。您可以创建一个函数,使用一个参数作为学校来计算距离,并在距离小于20英里时调用它,或者将数据库中的每个学校添加到一个新数组中(如果距离不足20英里),然后计算该数组。如果你做第二个选择,它将只在20英里以下的学校中循环,我推荐第一个选择