Hi everyone i have a question about a problem that i would like to do in swift and to see the best possible way to do that. I currently have an approach that i don't like and would be good if i can get some ideas about it.
Here it is the problem:
Example with LocationManager:
Example code:
var queue = DispatchQueue("q")
queue.async {
var locationCollected = Array<Location>()
// this will output multiple times
getLocation { location in
// add location to the collection
locationCollected.append(location)
}
// the current Q need to wait until all results are collected
return locationCollected
}
func getLocation() -> Location {
// this is the function that will return location
self.manager?.location(completion: { location in
// will provide location and update
completion(location)
}
}
Thank you much appreciated the help
If you want to adopt a linear flow of code approach then you can adopt the new async/await
construct but that will limit your iOS versions.
In general blocking threads is best avoided as it can cause deadlocks. You should use completion handlers to get your asynchronous result rather than blocking.
For the purposes of this answer I will stick with the approach in your question.
Based on the requirements in your question, let's create a function that:
We need to ensure only a single location fetch is active at a time, which we can do with a DispatchSemaphore
func getLocations(for duration: TimeInterval, completion: (([Location])->Void)) {
var queue = DispatchQueue("q")
queue.async {
let semaphore = DispatchSemaphore(0)
var locationCollected = [Location]()
let startTime = Date()
while (startTime.timeIntervalSinceNow > -duration) {
getLocation { location in
locationCollected.append(location)
semaphore.signal()
}
semaphore.wait()
}
completion(result)
}
}