Hey in my code the function "sendRequest" is called multiple times which sends a request to a server. The server processes all requests one after the other and sends back a multiple responses. Now I want to process these responses in the function "handleResponse", but in a serial queue. So handleResponse will only be called once at the same time. But now I have the case that my logs look like this:
[15.05.2023 11:28:00.711] DEBUG NetworkDataHandler:52 - start handleResponse
[15.05.2023 11:28:00.710] DEBUG NetworkDataHandler:52 - start handleResponse
[15.05.2023 11:28:00.713] DEBUG NetworkDataHandler:52 - start handleResponse
[15.05.2023 11:28:00.713] DEBUG NetworkDataHandler:52 - start handleResponse
[15.05.2023 11:28:00.714] DEBUG NetworkDataHandler:52 - start handleResponse
...
handleResponse is thus called several times, although it has not yet been completed. How can I get the callback to work serially?
Simplified code:
func sendRequest() { // is called several times
applicationNetworkManager().sendQuery(
...
successHandler: { response in
let workItem = DispatchWorkItem {
self!.handleResponse(response: response)
}
let serialQueue = DispatchQueue(label: "serialQueue", qos: .background)
serialQueue.async(execute: workItem)
}
)
}
func handleResponse(response: Response) {
Logger.d("start handleResponse")
// do some stuff and write response data to local storage
DispatchQueue.main.async {
// update ui
}
Logger.d("end handleResponse")
}
In sendRequest
you are creating a new dispatch queue each time you call let serialQueue = DispatchQueue(label: "serialQueue", qos: .background)
. Even though all of the queue instances have the same label, they are different queues.
You don't show how you create the class that contains sendRequest
, so I am not sure if there is one instance of this class or if you have multiple instances.
It is also best to avoid the .background
QoS; This QoS level can be starved for CPU in a low power situation. .utility
is a good choice.
Assuming you have one instance you would use something like:
class NetworkHandler {
let myQueue: DispatchQueue
init() {
self.myQueue = DispatchQueue(label:"serialQueue", qos: .utility)
}
}
You can then use this queue in your handler.