I've centralized API calls for my App in a class called APIService
.
Calls look like the one below:
// GET: Attempts getconversations API call. Returns Array of Conversation objects or Error
func getConversations(searchString: String = "", completion: @escaping(Result<[Conversation], APIError>) -> Void) {
{...} //setting up URLRequest
let dataTask = URLSession.shared.dataTask(with: request) { data, response, error in
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200, let _ = data
else {
print("ERROR: ", error ?? "unknown error")
completion(.failure(.responseError))
return
}
do {
{...} //define custom decoding strategy
}
let result = try decoder.decode(ResponseMultipleElements<[Conversation]>.self, from: data!)
completion(.success(result.detailresponse.element))
}catch {
completion(.failure(.decodingError))
}
}
dataTask.resume()
}
I'm executing API calls from anywhere in the Application like so:
func searchConversations(searchString: String) {
self.apiService.getConversations(searchString: searchString, completion: {result in
switch result {
case .success(let conversations):
DispatchQueue.main.async {
{...} // do stuff
}
case .failure(let error):
print("An error occured \(error.localizedDescription)")
}
})
}
What I would like to achieve now is to execute func searchConversations
for each character tapped by the user when entering searchString
.
This would be easy enough by just calling func searchConversations
based on a UIPressesEvent
being fired. Like so:
override func pressesEnded(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
guard let key = presses.first?.key else { return }
switch key.keyCode {
{...} // handle special cases
default:
super.pressesEnded(presses, with: event)
searchConversations(searchString: SearchText.text)
}
}
My problem is this now:
Whenever a new character is entered, I'd like to cancel the previous URLSession and kick-off a new one. How can I do that from inside the UIPressesEvent
handler?