Solving slow but successful server response on iOS

iosserver

I am trying to solve two situations here related to making POST requests and handling responses.

  1. Making a request and having request timed out due to no server response, as well as assuming that in this case nothing has been written in a database hosted on the server.
  2. Making a request and having request timed out, but now things are written on a server, and server could / will eventually send a response.
    So I am trying to figure out what should I do in each of these two situations. Situation no. 2 is most important for me, and I don't really have an idea how to solve it.

I only have a solution for the first situation, but I would be interested to hear opinion / best practices about how to solve that too.

I am using Swift 2.0 if that matters, so it is iOS, and I am using custom wrapper around NSURLSession and related classes to make requests.

As an additional info I can describe how my app works:

I create a model object, call it Data. So I send a JSON representation of that object to a server, write it into database, and get a response from a server that it is recorded.

This is a task assigned to my DataManager class (which is a singleton ), and it handles requests and responses. When it receives a response from a server, it updates an appropriate model object, and through delegation / notification updates UI.

When a user taps the send button, I show activity indicator and set an appropriate label's text to Sending… And that is where these two situations can eventually arise…

In situation no. 1, I will tell the user that request has timed out, cancel the request and show a retry button. Problem solved.

Situation no. 2 is trickier… The user will tap send button, and he will wait. But imagine if this happen:

  • data sent to a server is successfully written
  • but the server response was very slow and exceeds the timeout limit on a client app
  • I show the request failed message to a user, but the request hasn't failed actually
    So what can happen here, is that user will experience inconsistency between what he sees on a device and what is really on the server (at least for some short period of time).

So when next refresh occurs, the user will see the previously sent object, even if he has gotten the message which says "operation failed"

How do you handle this?

Best Answer

You could ping the server several times before you send a request and check the latency of the pings. Set your timeout greater than the maximum return time (say 2x to be generous). When your client sends a request to the server, send the latency information as well so the server doesn't timeout trying to reach the client.

You could make your pings in the background, for example 1 every 10 seconds, then use the past few pings. As it's a background process you can set the timeout incredibly long1 before you try the next ping as it should not affect the client's main usage.

If you cannot get a single ping response back to calculate latency it's pretty safe to say the server would not receive your initial message.

1While it could be long to test if you can get anything back at all you have to remember your client will probably dislike being stuck in a minute long "sending..." screen because you deemed that to be fine.

Related Topic