调用Reachability startNotifier后,网络状态将更改为0

时间:2013-02-13 09:39:53

标签: ios reachability

在我的iOS应用程序中,我需要使用Reachability来完成以下任务:

  1. 呈现视图控制器时,应用程序需要检查连接状态,并相应地显示连接图标图像(在线或离线)。
  2. 当用户停留在视图控制器上,并且互联网连接状态发生变化时,将通知应用程序更改,然后相应地执行某些任务。
  3. 我使用了Tony Million在我的应用程序中生成的Reachability类,但发生了一件奇怪的事情: 调用startNotified方法后,可访问性状态更改为0(NotReachable)

    以下是我的代码:

    BTLandingViewController.h

    #import <UIKit/UIKit.h>
    #import "MBProgressHUD.h"
    #import "Reachability.h"
    
    @interface BTLandingViewController : UIViewController <UIAlertViewDelegate>
    {
        __weak IBOutlet UIImageView *internetIndicator;
    
        MBProgressHUD *hud;
        Reachability *reach;
    
        UIAlertView *emptyRecordsAlert;
        UIAlertView *syncReminderAlert;
    }
    
    @end
    

    部分代码 BTLandingViewController.m

    #import "BTLandingViewController.h"
    
    @interface BTLandingViewController ()
    @end
    @implementation BTLandingViewController
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Initialize reachability
            reach = [Reachability reachabilityWithHostname:BTReachTestURL];
        }
        return self;
    }
    
    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
    
        // Register with reachability changed notification
        [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(reachabilityChanged:)
                                                 name:kReachabilityChangedNotification
                                               object:nil];
    
        NetworkStatus internetStatus = [reach currentReachabilityStatus]; // value = 1 or 2
    
        ***// PS: If there is connection, before [reach startNotifier], the internetStatus's   value reflects the connection status (1 or 2)***
    
        // Start notify reachability change
        [reach startNotifier];
    
        internetStatus = [reach currentReachabilityStatus]; // Value = 0;
    
        ***// PS: Even if there is connection, after [reach startNotifier], the internetStatus's value becomes 0***
    }
    

    感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我终于通过解决上面提到的startNotifier陷阱解决了这个问题。调用startNotifier会将网络状态更改为0,但我声明了一个变量,用于在呈现视图控制器时存储初始网络状态。然后在处理由reachabilityChanged通知触发的操作的方法中的if语句中使用变量的值。以下是我的代码:

<强> BTLandingViewController.h

#import <UIKit/UIKit.h>
#import "MBProgressHUD.h"
#import "Reachability.h"

@interface BTLandingViewController : UIViewController <UIAlertViewDelegate>
{
    __weak IBOutlet UIImageView *internetIndicator;

    MBProgressHUD *hud;
    NSInteger initialNetworkStatus;

    UIAlertView *emptyRecordsAlert;
    UIAlertView *syncReminderAlert;  
}

@end

<强> BTLandingViewController.m

#import "BTLandingViewController.h"
#import "BTSyncEngine.h"
#import "BTInstructorLoginViewController.h"
#import "BTGlobalParams.h"

@interface BTLandingViewController ()

@end

@implementation BTLandingViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)viewDidUnload {
    internetIndicator = nil;
    [super viewDidUnload];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Register with sync complete notification
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(syncCompleted:) name:@"BTSyncEngineSyncCompleted" object:nil];

    // Register with reachability changed notification
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(reachabilityChanged:)
                                             name:kReachabilityChangedNotification
                                           object:nil];

    Reachability *reach = [Reachability reachabilityWithHostname:BTReachTestURL];

    reach.reachableBlock = ^(Reachability * reachability){
        dispatch_async(dispatch_get_main_queue(), ^{
            initialNetworkStatus = 1;

            [internetIndicator setImage:[UIImage imageNamed:@"online_indicator.png"]];

            // Start syncing local records with the remote server
            [[BTSyncEngine sharedEngine] startSync];
            hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
            hud.labelText = @"Sync in progress";
        });
    };

    reach.unreachableBlock = ^(Reachability * reachability)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            initialNetworkStatus = 0;

            [internetIndicator setImage:[UIImage imageNamed:@"offline_indicator.png"]];

            // If the initial sync has been executed
            // then use the cached records on the device
            if ([[BTSyncEngine sharedEngine] initialSyncComplete]) {
                // Go to instructor login screen
                BTInstructorLoginViewController *instructorLoginViewController = [[BTInstructorLoginViewController alloc] init];
                [instructorLoginViewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
                [self presentViewController:instructorLoginViewController animated:YES completion:nil];
            }
            // If the initial sync has not been executed
            // show an alert view
            else {
                emptyRecordsAlert = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"Please connect to the internet to load data for the first time use." delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
                [emptyRecordsAlert show];
            }

        });
    };

    [reach startNotifier];

}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];

    // Unregister with reachability changed notification
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:nil];

    // Unregister with sync complete notification
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"BTSyncEngineSyncCompleted" object:nil];
}

- (void)syncCompleted:(NSNotification *)note
{
    // Update the global sync completed flag
    [[BTGlobalParams sharedParams] setSyncCompleted:YES];

    // Hide syncing indicator
    [MBProgressHUD hideHUDForView:self.view animated:YES];

    // Go to instructor login screen
    BTInstructorLoginViewController *instructorLoginViewController = [[BTInstructorLoginViewController alloc] init];
    [instructorLoginViewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
    [self presentViewController:instructorLoginViewController animated:YES completion:nil];
}

- (void)reachabilityChanged:(NSNotification *)note
{
    Reachability *reach = [note object];

    if ([reach isReachable] && !initialNetworkStatus) {

        [internetIndicator setImage:[UIImage imageNamed:@"online_indicator.png"]];

        // Start syncing local records with the remote server
        [[BTSyncEngine sharedEngine] startSync];
        hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
        hud.labelText = @"Sync in progress";

    }
}

@end