iosobjective-cafnetworking

How to timeout or detect slow response in AFHTTPSessionManager in AFNetworking?


With my code below, the failure block fires immediately if there is no internet connection - and that is good. But what if there is a connection, but no internet?

I've read this question: How to set a timeout with AFNetworking which suggests to use the reachabilityManager and the example in this answer shows the use - AFNetworking 2.0 queue request when device is offline with setReachabilityStatusChangeBlock does nothing.

BUT, if my simulator or phone is connected to my wifi network but does not have internet access (DNS, DHCP, or modem issues), my code at present continues to try to reach my API for a long time. I'm not downloading anything and I know my script and my server should respond in seconds so I know that after 5 seconds of inactivity, something is wrong.

So can I safely do a timeout, or can I use the reachabilityManager in my current script to detect if the script (not the internet) is not reachable and if so, how?

- (void)APICall:(NSMutableDictionary*)params {

    NSURL *baseURL = [NSURL URLWithString:BaseURLString];
    NSDictionary *parametersGetAuthCode = @{@"req": @"getauth"};

    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL];

    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    [manager POST:APIscript parameters:parametersGetAuthCode success:^(NSURLSessionDataTask *task, id responseObject) {
        if ([task.response isKindOfClass:[NSHTTPURLResponse class]]) {
            NSHTTPURLResponse *r = (NSHTTPURLResponse *)task.response;
            if ([r statusCode] == 200) {

            //do success stuff

            }
        }
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [alertView show];

        //do failure stuff

    }];

}

Solution

  • Just figure out what a reasonable timeout interval is for your app and set it on the AFHTTPSessionManager Request Serializer.

    Objective-C

    [manager.requestSerializer setTimeoutInterval:20.0];  
    

    Swift

    manager.requestSerializer.timeoutInterval = 20
    

    Add something to your UI, like a UIActivityIndicatorView or a "Downloading..." message so the user knows that something is happening.