I have been developing an app on iPhone using Swift. I am a newbie and I don't have much experience. I have a problem now. Once I started my app, I used timers for background processes. For instance I was calling functions to check if the response arrived from the server every 0.2 seconds. And that is not the proper way as you know. Now I'm trying to learn treading in swift. What I exactly need is, I need to know when a background process is finished and I need to start another background process.
DispatchQueue.global(cos: .userInteractive).async{
//some request and parsing json
}
Now, when the task is finished I have to start another task. In detail, I will check the last version required, than I will make a login request, than I will pull some images from background, than I will finish the animation. That's why I need to know how to know a background thread is finished so I can start other thread. I think I should use serial queue right? One more thing, I have to check if process took so much time, so will warn the user about connection.
DispatchQueueHelper.delay(byseconds: x, cos:.background){
// will this work for killing the thread
}
You can use a dispatch group to keep track of your actions:
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
dispatchGroup.leave()
dispatchGroup.notify(queue: .main) {
// Back on main
}
But this is often when you create multiple requests at once. Normally network requests have their own completion block that will alert you when it's completed. Something like:
URLSession.shared.dataTask(with: url) {(data, response, error) in
// Task is done
}
In your function that you call to execute the request you should leave an completionBlock as:
func execute(request url: URLRequest, completion: (() -> ()) {
URLSession.shared.dataTask(with: url) {(data, response, error) in
completion()
}
}
You of course shouldn't call the completion immediately as you want to handle the data and send it inside.
In swift 5 they introduced Result<Any, Error>
which is a great thing to send in your completionBlock completion: ((Result<Model, Error>) -> ())
On the other side it will look something like:
execute(request: request { result in
switch result {
case .success(let model):
// Handle data
case .failure(let error):
// Handle error
}
})