1

I have a view that i display when there is no internet connection, and if there is no internet connection I check to see if it has be restored, with this method. Which is first called in viewDidLoad

-(void)checkInternet {

    internetReach = [Reachability reachabilityForInternetConnection];
    [internetReach startNotifier];
    NetworkStatus netStatus = [internetReach currentReachabilityStatus];

    switch (netStatus){
        case ReachableViaWWAN:{
            isReachable = YES;
            NSLog(@"4g");
            noInternetView.hidden = YES;
            break;
        }
        case ReachableViaWiFi:{
            isReachable = YES;
            noInternetView.hidden = YES;
            NSLog(@"wifi");
            break;
        }
        case NotReachable:{

            NSLog(@"NONE");
            noInternetView = [[CheckInternetView alloc] initWithFrame:self.view.bounds];
            [self.view addSubview:noInternetView]; //IT IS NOT ADDED??
            isReachable = NO;
            [self checkInternet];
            break;
        }
    }
}

And the method is called over and over again if there is no internet, but why isn't noIntenertView coming onto the view controller?

EDIT

Here is the CheckInternetView Class

#import "CheckInternetView.h"

@implementation CheckInternetView

- (id)initWithFrame:(CGRect)frame {

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenWidth = screenRect.size.width;
    CGFloat screenHeight = screenRect.size.height;

    self = [super initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight)];
    if (self) {

        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 60)];
        label.textAlignment = NSTextAlignmentCenter;
        label.numberOfLines = 2;
        [label setCenter:CGPointMake(self.frame.size.width / 2 , self.frame.size.height / 2 - 25)];
        label.text = @"You've lost your internet connection. Please connect to internet.";

        UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
        spinner.frame = CGRectMake(0, 0, 80, 80);
        [spinner setCenter:CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2 + 40)];
        [spinner startAnimating];

        label.textColor = whiteColorAll;
        spinner.color = whiteColorAll;

        [self setBackgroundColor:[UIColor blackColor]];

        [self addSubview: spinner];
        [self addSubview: label];

    }


    return self;

}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
james brown
  • 250
  • 1
  • 4
  • 11

1 Answers1

0

Since you are calling the checkInternet on the main UI thread and create a infinite recursive loop there is no time for the UI to update. It would only update after you return from viewDidLoad. But that does not happen until you actually have a valid internet connection. If you do not have one, you will loop.

To fix this: move the call to checkInternet into a background thread. If you then need to present the view make sure that again happens on the main thread.

Take a look here to see how to properly create a new background thread. And here to see how to run the need UI code on the main thread again.

Note that you probably will end up with tons of CheckInternetView instances because you add them over and over again. It would be better to only create and add one if there is none yet present.

Additionally your code will be quite performance intensive and might even cause a crash because you just recurse without a proper timeout or break condition. It would be better to check the internet every second or every half second or some time interval in that range. And you might want to do it in a continuous loop rather than in a recursion to reduce the impact for the heap and stack.

Community
  • 1
  • 1
luk2302
  • 55,258
  • 23
  • 97
  • 137
  • @jamesbrown i included the links to exactly that question ;) – luk2302 Jun 20 '15 at 20:33
  • Right, I fixed the problem of it adding the view a million times. And got the background thread working. What would be the simplest way of checking every second or so? And why would looping be better than recursive? Sorry for all the questions, but I would really appreciate the help :) – james brown Jun 20 '15 at 20:44
  • just sleeping should work because you actually now have a different thread you are operating on: http://stackoverflow.com/questions/15004712/what-is-the-ios-sleep-function and looping is better because recursion with recursion you just put much more data on the stack and the heap than you actually need. – luk2302 Jun 20 '15 at 20:48
  • hey, one last thing, would I use a while loop to check while (!connection)? is that what you mean instead of recurssive – james brown Jun 20 '15 at 22:57
  • @jamesbrown I would suggest `while ((netStatus = [internetReach currentReachabilityStatus]) == NotReachable) { do your switch etc. }` – luk2302 Jun 21 '15 at 07:34