Search code examples
iosios7reachability

iOS: Reachability - startNotifier fails after returning to app


I have Reachability working exactly as suggested as in this thread.

I am using the open source Reachability. However I am not using blocks but notifications, hence the process is pretty similar to the Apple's Reachability code.

The first time I start the app, I run this and it works great.

Reachability *reachability = [reach hostReachability];
[reachability startNotifier];

The reachabilityChanged: event is firing:

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

However once I press the home button and come back to the app, the startNotifier returns internally a NO instead of a YES.

    // Set it as our reachability queue, which will retain the queue
    if(!SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, self.reachabilitySerialQueue))
    {
#ifdef DEBUG
        NSLog(@"SCNetworkReachabilitySetDispatchQueue() failed: %s", SCErrorString(SCError()));
#endif
      ...
      return NO;

and hence the event above is never fired again.

Unless I am using this wrongly and startNotifier should only be called once in init when reachability is instantiated and never again?

self.hostReachability = [Reachability reachabilityWithHostname:_HOST];

Solution

  • You should only need to call [self.hostReachability startNotifier] once on init/load. Here's a rundown of your basic needs, using notifications rather than the block method on the linked thread:

    1. Add the tonymillion/Reachability library to your project.

    2. Create property for your Reachability object to make sure it's retained, eg.

      @interface ViewController () {
        NSString *_HOST;
      }
      @property Reachability *hostReachability;
      @end
      
    3. Register for change notifications, and start the notifier, eg.

      - (void)viewDidLoad
      {
        [super viewDidLoad];
      
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(reachabilityChanged:)
                                                     name:kReachabilityChangedNotification
                                                   object:nil];
      
        _HOST = @"www.google.com";
        self.hostReachability = [Reachability reachabilityWithHostname:_HOST];
        [self.hostReachability startNotifier];
      }
      
      - (void)viewDidUnload
      {
        [super viewDidUnload];
      
        [[NSNotificationCenter defaultCenter] removeObserver:self];
      }
      
    4. Finally, create a reachabilityChanged: method to handle your response to Reachability changes, eg.

      - (void)reachabilityChanged:(NSNotification*)notification
      {
        Reachability *notifier = [notification object];
        NSLog(@"%@", [notifier currentReachabilityString]);
      }
      

    Note: If you press the Home button and unload the app, changes in Reachability should fire a notification immediately upon returning to the app.