1

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

  1. 渲染视图控制器时,应用程序需要检查连接状态,并相应地显示连接图标图像(在线或离线)。
  2. 当用户停留在视图控制器上时,如果互联网连接状态发生变化,应用程序将收到更改通知,然后相应地执行一些任务。

我在我的应用程序中使用了由 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***
}

谢谢您的帮助。

4

1 回答 1

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
于 2013-02-14T02:33:19.853 回答