Search code examples
iosuialertviewreachability

ios - Reachability notifications multiple alerts


I'm using Tony Million's version of Reachability (problem was the same with Apple's version of Reachability) to check on my app if there is an active internet connection.

Here is what I want:
when the view loads or appears, it checks if there is an internet connection. if there isn't any, if shows an alert, and on click, it tries again, until there is an active connection.

If there is a connection, the view is loaded normally. When Reachability notifies of connection loss, it displays the same alert again. Here is my actual code:

//in the implementation:
BOOL internetActivated;

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self testInternetConnection];
    NSLog(@"%d", internetActivated);
    if(internetActivated == NO)
    {
        UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Pas de connexion internet" message:@"Une connexion est requise pour utiliser l'application" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Réessayer", nil];
        [alert show]; 
    }
    else {
        [self onAppearFunction];
    }
}


- (void)viewDidAppear:(BOOL)animated
{
    [self testInternetConnection];
    if(internetActivated == NO)
    {
        UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Pas de connexion internet" message:@"Une connexion est requise pour utiliser l'application" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Réessayer", nil];
        [alert show]; 
    }
    else {
        [self onAppearFunction];
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    if (buttonIndex == 0)
    {
        [self viewDidLoad];
    }
}

- (void)testInternetConnection
{
    __unsafe_unretained typeof(self) weakSelf = self;
    internetReachableFoo = [Reachability reachabilityWithHostname:@"www.google.com"];

    // Internet is reachable
    internetReachableFoo.reachableBlock = ^(Reachability*reach)
    {
        // Update the UI on the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            internetActivated = YES;
            NSLog(@"Yayyy, we have the interwebs!");
        });
    };

    // Internet is not reachable
    internetReachableFoo.unreachableBlock = ^(Reachability*reach)
    {
        // Update the UI on the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            internetActivated = NO;
            UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Pas de connexion internet" message:@"Une connexion est requise pour utiliser l'application" delegate:weakSelf cancelButtonTitle:nil otherButtonTitles:@"Réessayer", nil];
            [alert show];
            NSLog(@"Someone broke the internet :(");
        });
    };

    [internetReachableFoo startNotifier];
}

Multiple problems:
1) InternetActivated starts as "NO", even though I call [self testInternetConnection] before testing the if condition. It should be updated to YES, shouldn't it?

2) Even when I have internet connection, the UIAlertView inside the testInternetConnection method keeps getting called. Actually: three or four times the second alert gets called (inside the testInternet method), and then three or four times the first alert view gets called, the one inside the viewDidLoad method.

By the way, I noticed that this NSLog: NSLog(@"Yayyy, we have the interwebs!"); gets called more than one time on every [self testInternetConnection] call.

I'm completely messing the alert calls up and it's driving me crazy!

Thanks for your help

UPDATE:

I managed to avoid the multiple alert by setting a BOOL to true when it's loaded and false when it gets clicked away to avoid multiple alerts from stacking up. Only thing is I want the internetActivated BOOL to be updated before I check it in the if...


Solution

  • Remove the code from viewdidload

    Bool alertIsShowing = NO;
    
    - (void)viewDidAppear:(BOOL)animated
    {
        if (! alertIsShowing)
            [self testInternetConnection];
    }
    
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
        alertIsShowing = NO;
        if (buttonIndex == 0)
        {
            [self testInternetConnection];
        }
    }
    
    - (void)testInternetConnection
    {
        __unsafe_unretained typeof(self) weakSelf = self;
        internetReachableFoo = [Reachability reachabilityWithHostname:@"www.google.com"];
    
        // Internet is reachable
        internetReachableFoo.reachableBlock = ^(Reachability*reach)
        {
            // Update the UI on the main thread
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"Yayyy, we have the interwebs!");
                [self onAppearFunction];
            });
        };
    
        // Internet is not reachable
        internetReachableFoo.unreachableBlock = ^(Reachability*reach)
        {
            // Update the UI on the main thread
            dispatch_async(dispatch_get_main_queue(), ^{
                UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Pas de connexion internet" message:@"Une connexion est requise pour utiliser l'application" delegate:weakSelf cancelButtonTitle:nil otherButtonTitles:@"Réessayer", nil];
                [alert show];
                alertIsShowing = YES;
                NSLog(@"Someone broke the internet :(");
            });
        };
    
        [internetReachableFoo startNotifier];
    }