Is your intention here to create a synchronous function that will block and wait until the async request completes?
If so, you're almost there but you need to change the Semaphore to start with 0 rather than 1 (decrementing from 1 to 0 won't stop execution, it needs to go negative), and you need to move the wait() call outside the closure, otherwise you aren't stopping the function from returning and instead would be blocking your closure from ever completing.
func customRequest(zipCode: String) -> Bool {
var response = false
let dispatchQueueProcess = DispatchQueue.global(qos: .userInitiated)
let semaphore = DispatchSemaphore(value: 0)
// Start async work on background thread, current function's thread
// execution point will then immediately move to the line
// after the closing brace
dispatchQueueProcess.async {
apiRequest(zipCode: zipCode) { apiResponse in
if let apiResponse = apiResponse {
response = apiResponse
} else {
print("Server did not Response")
}
// Tell the original function's thread that it is OK to continue
semaphore.signal()
}
}
// Immediately wait for the semaphore after starting the async work so that
// the customRequest(zipCode:) function pauses here until the semaphore is
// signalled in the closure.
semaphore.wait()
// Once the semaphore.signal() call happens in the async closure execution
// resumes, and the response variable can now be returned with the updated
// value.
return response
}
You might find that you don't actually want to make a synchronous function like this, because if you call this from the main queue you will freeze the UI until the response is received.
Edit: This example should copy-paste run in a Playground
import Foundation
// template function to simulate the API call
func apiRequest(zipCode: String, response: (Bool?)->Void) {
sleep(3)
response(true)
}
func customRequest(zipCode: String) -> Bool{
var response = false
let dispatchQueueProcess = DispatchQueue.global(qos: .userInitiated)
let semaphore = DispatchSemaphore(value: 0)
dispatchQueueProcess.async {
apiRequest(zipCode: zipCode) { apiResponse in
if let apiResponse = apiResponse {
response = apiResponse
} else {
print("Server did not Response")
}
semaphore.signal()
}
}
semaphore.wait()
return response
}
print("Result: (customRequest(zipCode: "90030"))")
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…