iosnetwork-programmingreachabilityserver-communication

Reachability not working


I am currently writing a game which needs an internet connection (TCP to server). I'm attempting to utilize the Reachability class from Apple, but it doesn't work. I'm new to NotificationCenter and Reachability, so please excuse me if this is a stupid question.

Reachability related props in LoginViewController.h

@property (nonatomic) Reachability *hostReachability;
@property (nonatomic) Reachability *internetReachability;
@property (nonatomic) Reachability *wifiReachability;
@property BOOL internetActive;
@property BOOL hostActive;

In the LoginViewController.m

//Reachability
    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handleNetworkChange:) name: kReachabilityChangedNotification object: nil];

    NSString* hostIP = @"<my server IP is here, removed for obvious reasons>";

    hostReachability = [Reachability reachabilityWithHostname:hostIP];

    [hostReachability startNotifier];

    NetworkStatus hostStatus = [internetReachability currentReachabilityStatus];

    if(hostStatus == NotReachable) {NSLog(@"no");}
    else if (hostStatus == ReachableViaWiFi) {NSLog(@"wifi"); }
    else if (hostStatus == ReachableViaWWAN) {NSLog(@"cell"); }

    hostReachability = [Reachability reachabilityForInternetConnection];

    [internetReachability startNotifier];

    NetworkStatus internetStatus = [internetReachability currentReachabilityStatus];

    if(internetStatus == NotReachable) {NSLog(@"no");}
    else if (internetStatus == ReachableViaWiFi) {NSLog(@"wifi"); }
    else if (internetStatus == ReachableViaWWAN) {NSLog(@"cell"); }

handleNetworkChange: procedure

- (void)handleNetworkChange:(NSNotification*)notification{
    NetworkStatus internetStatus = [internetReachability currentReachabilityStatus];

    switch (internetStatus) {
        case NotReachable:
        {
            NSLog(@"No internet connection");
            self.internetActive = NO;
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No internet connection"
                                                            message:@"Could not connect to the internet. Please try again later."
                                                           delegate:nil
                                                  cancelButtonTitle:@"OK"
                                                  otherButtonTitles:nil];
            [alert show];
        }
        break;
        case ReachableViaWiFi:
        {
            NSLog(@"The internet is working via WIFI.IN AGENDA");
            self.internetActive = YES;

            break;
        }
        case ReachableViaWWAN:
        {
            NSLog(@"The internet is working via WWAN.IN AGENDA");
            self.internetActive = YES;

            break;
        }

        default:
        break;
    }

    NetworkStatus hostStatus = [hostReachability currentReachabilityStatus];
    switch (hostStatus)
    {
        case NotReachable:
        {
            NSLog(@"A gateway to the host server is down.IN AGENDA");
            self.hostActive = NO;
            NSLog(@"No internet connection");
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No connection to host"
                                                            message:@"Could not connect to the host server. Please try again later."
                                                           delegate:nil
                                                  cancelButtonTitle:@"OK"
                                                  otherButtonTitles:nil];
            [alert show];

            break;
        }
        case ReachableViaWiFi:
        {
            NSLog(@"A gateway to the host server is working via WIFI.IN AGENDA");
            self.hostActive = YES;

            break;
        }
        case ReachableViaWWAN:
        {
            NSLog(@"A gateway to the host server is working via WWAN.IN AGENDA");
            self.hostActive = YES;

            break;
        }
    }

When running the application, I always get "no no" in the terminal, regardless of whether or not I'm actually connected to the internet, and whether or not the server software is running.

Thanks in advance.


Solution

  • The main problem here is a typo in your code; the line reading hostReachability = [Reachability reachabilityForInternetConnection]; in LoginViewController.m should be internetReachability = [Reachability reachabilityForInternetConnection];. The way it currently is, you never instantiate internetReachability, and then I guess [internetReachability currentReachabilityStatus] will always return nil.

    Below is a basic example you can test with:

    @interface LoginViewController ()
    
    // ...
    
    @property (strong, nonatomic) Reachability *hostReachability;
    @property (strong, nonatomic) Reachability *internetReachability;
    @property (strong, nonatomic) Reachability *wifiReachability;
    
    @end
    
    @implementation LoginViewController
    
    // ...
    
    - (void)setupReachabilityMonitoring
    {
        [NSNotificationCenter.defaultCenter addObserver:self
                                               selector:@selector(reachabilityChanged:)
                                                   name:kReachabilityChangedNotification
                                                 object:nil];
    
        _hostReachability = [Reachability reachabilityWithHostName:@"8.8.8.8"];
        [_hostReachability startNotifier];
    
        _internetReachability = [Reachability reachabilityForInternetConnection];
        [_internetReachability startNotifier];
    
        _wifiReachability = [Reachability reachabilityForLocalWiFi];
        [_wifiReachability startNotifier];
    
        [self logReachabilityStatus];
    }
    
    - (void)reachabilityChanged:(NSNotification *)notification
    {
        if ([notification.object isKindOfClass:Reachability.class]) {
            [self logReachabilityStatus];
        }
    }
    
    - (void)logReachabilityStatus
    {
        NSString *hostStatus = _hostReachability.currentReachabilityStatus ? @"up" : @"down";
        NSString *internetStatus = _internetReachability.currentReachabilityStatus ? @"up" : @"down";
        NSString *wifiStatus = _wifiReachability.currentReachabilityStatus ? @"up" : @"down";
    
        NSLog(@"Internet is %@, wifi is %@, host is %@", internetStatus, wifiStatus, hostStatus);
    }
    
    @end