Anthony
Anthony

Reputation: 2801

How to define a reachability timeout on ios

I use the Reachability class to know if I have an internet connection available. The problem is when wifi is available but not internet, the - (NetworkStatus) currentReachabilityStatus method take too much time.

my code:

Reachability* reachability = [Reachability reachabilityWithHostName:@"www.apple.com"];
NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];

The application "freeze" temporarily on the second line. How to define the maximum time for this waiting ?

Upvotes: 6

Views: 2486

Answers (2)

user1131259
user1131259

Reputation: 11

I was having issues with the same thing but I found a way to specify a timeout. I replaced this method inside the Reachability Class from Apple.

- (NetworkStatus)currentReachabilityStatus
{
NSAssert(_reachabilityRef != NULL, @"currentNetworkStatus called with NULL     SCNetworkReachabilityRef");
//NetworkStatus returnValue = NotReachable;
__block SCNetworkReachabilityFlags flags;

__block BOOL timeOut = NO;
double delayInSeconds = 5.0;

dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(delay, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(void){

    timeOut = YES;

});

__block NetworkStatus returnValue = NotReachable;

__block BOOL returned = NO;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))
    {
        if (_alwaysReturnLocalWiFiStatus)
        {
            returnValue = [self localWiFiStatusForFlags:flags];
        }
        else
        {
            returnValue = [self networkStatusForFlags:flags];
        }
    }
    returned = YES;

});

while (!returned && !timeOut) {
    if (!timeOut && !returned){
        [NSThread sleepForTimeInterval:.02];
    } else {
        break;
    }
}

return returnValue;
}

Upvotes: 0

Rob
Rob

Reputation: 437482

I don't think so. But more importantly, I don't think you'd want to if you could (you may get false positives). Let Reachability run it's course.

If you look at the Reachability demo project, the notion isn't to invoke reachabilityWithHostName and check currentReachabilityStatus when you need the Internet. You invoke currentReachabilityStatus at during your app delegate's didFinishLaunchingWithOptions, set up a notification, and Reachability will tell you when the Internet connectivity has changed. I find that subsequent checks to currentReachabilityStatus are plenty fast (regardless of connectivity) when I (a) setup reachability at startup; but (b) check for connectivity in a just-in-time manner.

And if you absolutely need to start your processing immediately, then the question is whether you can push that into the background (e.g. dispatch_async()). E.g., my app retrieves updates from the server, but because that's happening in the background, neither me nor my user are aware of any delays.

Upvotes: 3

Related Questions