Reputation: 1175
I'm curious on the user experience for an user, while they wait for a network call to complete over cancelling the existing non deterministic request. Let me add more context. I'm prefetching data for my app that is later used. When the user hits the button, we use this data to load a screen. Instead of showing a spinner to the user and waiting on the network call to complete, we wanted to give them a better user experience.
class TestInteractor {
var currentTask: HTTPTask?
var content: SomeContent?
func getData(_ id: String, completion: Result<SomeContent, Error>) {
currentTask = URLSession.shared().dataTask(with: request) {
// check for no error
// set content here
}
}
var hasContent: Bool {
return content != nil
}
}
Here is the issue, if the prefetch is still in process (due to a bad network) should I let the user wait until this call completes or just cancel the task and restart a new call.
Canceling an existing network call can be implemented as below:
func getData(_ id: String) {
if let task = currentTask {
task.cancel()
currentTask = nil
}
// Continue with a new network call
}
Or should I add a new property to the TestInteractor
and check if the network is still in progress and wait?
var isNetworkCallInProgress: Bool {
return currentTask?.state == running
}
Upvotes: 1
Views: 469
Reputation: 52538
First, your app has a network activity indicator. Make a counter of how many network tasks you started, how many have finished, and turn the network activity indicator on or off when the count changes from 0 to 1 or from 1 to 0. That shows network activity very nicely.
Second, in your data model you will have items with correct data, items that are being loaded, and items that are not being loaded. Write code to display each kind of item. When a network request finishes, it updates your data model, and that redraws the corresponding item.
Upvotes: 1
Reputation: 2201
There could be numerous reasons why a network request hasn’t completed yet; your server may be a bit overwhelmed; the client’s network speed may be a bit slow. It may be a waste to abort the work and start over. And whose to say that restarting the task is going to change any current impediment.
I’d say wait on the running task until it completes. If the pre-fetch completes before we need it, great, the pre-fetch saved time. But if it’s not yet done by the time we need it, if you let it finish, that’ll still save time rather than restarting it (the restarted task isn’t gonna magically be faster than the previous one just because we restarted it) so the pre-fetch was useful in this case too. So by allowing the request to complete, you’re maximizing the utility of the pre-fetch mechanism. Plus, if you choose to restart a task because pre-fetch couldn’t complete in time, what if your average user is actually faster than your average serving time for that request? Lol who knows, you might end up doubling your server load for the average case. Better that you have a design that is decoupled from things like that.
Upvotes: 1
Reputation: 153
You can give the user a choice, you could add a refresh button to reset the call or let them wait for it.
If you want to ask them if it's working, you could just push an alert asking them if they want to refresh the call while running the prefetch in the background.
let alert = UIAlertController(title: "Message Title", message: "body text", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "button", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
This is the code for an alert. I would personally check and see if the process is taking long and then push out the alert asking the to either refresh or wait.
Upvotes: 0