I'm building a bus predictions app using the NextBus API that will help users get prediction times and bus information. I've implemented a function that takes the user's current location and a chosen address and returns a list of 10 bus routes that minimize travel distance and time.
Here's the @IBAction
that triggers the aforementioned function:
@IBAction func findAWayPressed(_ sender: UIButton) {
// Hide confirm button.
confirmButton.isHidden = true
// Setup loading HUD.
let blue = UIColor(red: 153/255, green: 186/255, blue: 221/255, alpha: 1.0)
SVProgressHUD.setBackgroundColor(blue)
SVProgressHUD.setStatus("Finding a way for you...")
SVProgressHUD.setBorderColor(UIColor.black)
SVProgressHUD.show()
// Finds a list of ten bus routes that minimizes the distance from the user and their destination.
WayFinder.shared.findAWay(startCoordinate: origin!, endCoordinate: destination!)
SVProgressHUD.dismiss()
}
The problem is that confirmButton.isHidden = true
and the SVProgressHUD lines only seem to do anything after the WayFinder.shared.findAWay()
executes. The HUD displays for a brief moment before being immediately dismissed by SVProgressHUD.dismiss()
.
Here's the findAWay
function:
func findAWay(startCoordinate: CLLocationCoordinate2D, endCoordinate: CLLocationCoordinate2D) {
// Get list of bus routes from NextBus API.
getRoutes()
guard !self.routes.isEmpty else {return}
// Initialize the the lists of destination and origin stops.
closestDestinations = DistanceData(shortestDistance: 1000000, stops: [])
closestOrigins = DistanceData(shortestDistance: 1000000, stops: [])
// Fetch route info for every route in NextBus API.
var routeConfigsDownloaded: Int = 0
for route in routes {
// Counter is always one whether the request fails
// or succeeds to prevent app crash.
getRouteInfo(route: route) { (counter) in
routeConfigsDownloaded += counter
}
}
while routeConfigsDownloaded != routes.count {}
// Iterate through every stop and retrieve a list
// of 10 possible destination stops sorted by distance.
getClosestDestinations(endCoordinate: endCoordinate)
// Use destination stop routes to find stops near
// user's current location that end at destination stops.
getOriginStops(startCoordinate: startCoordinate)
// Sort routes by adding their orign distance and destination
// distance and sorting by total distance.
getFoundWays()
}
private func getRouteInfo(route: Route, completion: @escaping (Int) -> Void) {
APIWrapper.routeFetcher.fetchRouteInfo(routeTag: route.tag) { (config) in
if let config = config {
self.routeConfigs[route.tag] = config
} else {
print("Error retrieving route config for Route \(route.tag).")
}
completion(1)
}
}
Why would the code in @IBAction
not execute in order? How could the hud not show on screen before findAWay
was called? Any ideas?