class a {
b().download ({ data in
})
}
class b{
func download (downloadedData: @escaping (_ data: Data? ) -> Void ) {
c().download()
}
}
class c {
func download () -> Data {
let semaphore = DispatchSemaphore(value: 0)
NetworkManager().downloadRequest: { (result: Result<Data, Error>) in
switch result {
case .success(let success)
......
case .failure(let error):
.....
}
semaphore.signal()
}
)
semaphore.wait()
return data
}
}
Class a initiates the download and class c interacts with network manager to download the data. Class c issues semaphore wait as soon as it sends request to download the data and issues signal when download completes. Is there a way to issue signal from class a when download is in progress. Basically class a should be able to skip wait by issuing signal command
Ok, what is the best practice other than async/wait as I have to implement before this fall.
Already written:
Use completion handler properly
Something like this:
class A {
func aMethod() {
B().download(downloadedData: { data in
guard let data = data else {
return
}
//Use `data` here...
})
}
}
class B {
func download(downloadedData: @escaping (_ data: Data? ) -> Void ) {
NetworkManager().downloadRequest {result in
switch result {
case .success(let data):
//.....
downloadedData(data)
case .failure(let error):
print(error)
//...
downloadedData(nil)
}
}
}
}
There's one simple principle: Never try to use asynchronous methods synchronously. You may want to use semaphores when you have multiple background threads and make them work together with some limited resources. But never for just waiting an asynchronous task to finish.