0

Sometimes a POST request with AFHTTPSessionManager executes the failure block with the following error: The network connection was lost. BUT the server side code executes successfully, sending a 200 OK response. How is that possible and what to do about it? What is a good strategy in general if a network connection is lost while the server executes a routine (successfully)? Could it be a problem with the AFNetworkReachabilityManager? I have it set up like this in the AppDelegate:

// Monitor network connection
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
switch (status) {
  case AFNetworkReachabilityStatusReachableViaWWAN:
  case AFNetworkReachabilityStatusReachableViaWiFi:
    DDLogInfo(@"AFNetworkReachabilityStatusReachableViaWiFi:");

    // Resume callbacks for remote operations
    [[[TSHTTPSessionManager sharedManager] operationQueue] setSuspended:NO];

    // Notify app
    [[NSNotificationCenter defaultCenter] postNotificationName:TSDidConnectToNetworkNotification
                                                        object:self userInfo:nil];
    break;
  case AFNetworkReachabilityStatusNotReachable:
    DDLogInfo(@"AFNetworkReachabilityStatusNotReachable:");

    // Suspend callbacks for remote operations
    [[[TSHTTPSessionManager sharedManager] operationQueue] setSuspended:YES];

    // Notify app
    [[NSNotificationCenter defaultCenter] postNotificationName:TSDidDisconnectFromNetworkNotification
                                                        object:self userInfo:nil];
    break;
  default:
    break;
}
}];

EDIT: I guess I did not make myself clear: The question is not about AFNetworkReachabilityManager (I just added the code to show how the app detects connectivity issues and forwards them as notifications such that other parts of the app get notified if they decide to do so). The questions is about a request (POST) which is transmitted successfully to the server which causes the server side code to execute. At the same time, and before the server is able to send its response, the connection is lost, which in turn causes the client side failure block to execute (after the network is reachable again but that does not really make a difference I guess). How do I know on the client side that the server succeeded nonetheless?

Tomodyne
  • 1
  • 1
  • Just found that this issue might be related to: http://stackoverflow.com/questions/26806850/http-disconnect-timeout-between-request-and-response-handling – Tomodyne May 10 '15 at 10:41

1 Answers1

0

If a device loses connectivity, AFNetworking's underlying AFHTTPRequestOperation and NSURLSessionDataTask objects will fail immediately. All you're doing by suspending the operationQueue is preventing the completion blocks you've set from running, so you don't hear about the failure until the connection comes back online and the operationQueue is resumed.

In general, when dealing with connectivity issues, it's simplest merely to handle it like any other failure. Perhaps present an error message to the user letting them know their connection is offline and to try their request again when connectivity is restored. If you really, really need to you can build a convenience wrapper around the various AFNetworking calls that attempts to retry them on failure or loss of connectivity, but that seems like a lot of work for little benefit, given you have no idea when connectivity will resume. For all you know the user has switched away from your app and it was killed in the background. But your current approach is certainly not the right way.

Jon Shier
  • 12,200
  • 3
  • 35
  • 37
  • Well, but that does not answer my question which is about a POST request which is executed successfully on the server side and then, right before the server can send its response, the network connection is lost. How do I know on the client side that the server succeeded although my failure block is executed? – Tomodyne May 10 '15 at 08:10
  • Actually, it does answer your original requisition regarding why you never receive your 200 response. But as to how you can know about the 200 response: you don't, until the client is able to receive that fact from the server. If the connection is lost before that time, there's no standard mechanism to achieve what you want. Of course, if you have control over the backend there are likely several ways you could accomplish what you want but the real question is whether it's worth the work. – Jon Shier May 10 '15 at 22:44