使用AFNetworking在didFinishLaunching中检查可达性,然后使用RESideMenu显示视图控制器

时间:2014-12-26 10:10:10

标签: ios afnetworking reachability residemenu

我在我的应用中使用AFNetworking,我正在通过内置类检查互联网连接。这是代码,

- (void) startInternetConnectivityMonitoring
{
    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status)
    {
        switch (status) {
            case AFNetworkReachabilityStatusUnknown:
            case AFNetworkReachabilityStatusReachableViaWWAN:
            case AFNetworkReachabilityStatusReachableViaWiFi:
                break;
            case AFNetworkReachabilityStatusNotReachable:
                break;
            default:
                break;
        }

        NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status));

    }];

    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
}

我可以通过此功能检查它,

- (BOOL) connected {
    return [AFNetworkReachabilityManager sharedManager].reachable;
}

我也在我的应用中使用RESideMenu来设置侧边菜单,这是我的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [self startInternetConnectivityMonitoring];

    RootViewController *rootView = [[RootViewController alloc] init];
    [rootView awakeFromNib];
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = rootView;
    [self.window makeKeyAndVisible];
    return YES;
}

除了FirstViewController之外,所有其他视图控制器都能正常工作。在FirstViewController中,我正在调用网络请求,在此之前,我会检查互联网连接。这是问题所在。每一次,它都会向我展示FirstViewController的No internet。因为,虽然它要求网络请求,AFNetworking不会更新互联网的状态。更新可能是几秒钟的摩擦,但它的更新速度不快。因为,我知道这个问题,我不想应用补丁来解决这个问题。我试过不同的东西来解决这个问题。使用的,

sleep(2);

返回YES之前

didFinishLaunchingWithOptions...

dispatch_synq - 冻结应用

dispatch_asynq - 不起作用

.. and many other hacky ways - 没有帮助。

5 个答案:

答案 0 :(得分:3)

不幸的是,确定连接需要一段时间,因此可能不会发生。但是,您可以注册接收可达性通知,而不是假设您有互联网连接。在AppDelegate中,didFinishLaunchingWithOptions:launchOptions开始监控:

[[AFNetworkReachabilityManager sharedManager] startMonitoring];

在FirstViewController viewDidLoad或viewWillAppear中,注册以接收通知:

 [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(reachabilityChanged:)
                                              name:AFNetworkingReachabilityDidChangeNotification
                                            object:nil];

然后在FirstViewController中添加一个方法来处理通知:

- (void)reachabilityChanged:(NSNotification *)notification
{       
    if([[AFNetworkReachabilityManager sharedManager].isReachable)
    {
        // Do web service stuff here
    }
    else
    {
        // Do non webservice stuff
    }

如果您需要知道状态是什么,可以从通知的userInfo字典中获取:

- (void)reachabilityChanged:(NSNotification *)notification
{
    NSLog(@"Rechability Changed: %@", notification.userInfo);
    BOOL reachable;
    NSInteger status = [[notification.userInfo objectForKey:@"AFNetworkReachabilityNotificationStatusItem"] integerValue];
    switch(status)
    {
        case AFNetworkReachabilityStatusNotReachable:
            NSLog(@"No Internet Connection");
            reachable = NO;
            break;
        case AFNetworkReachabilityStatusReachableViaWiFi:
            NSLog(@"WIFI");
            reachable = YES;
            break;
        case AFNetworkReachabilityStatusReachableViaWWAN:
            NSLog(@"3G");
            reachable = YES;
            break;
        default:
            NSLog(@"Unkown network status");
            reachable = NO;
        break;
    }
    // do stuff with reachable
}

AFReachabilityManager确定网络状态后立即发送通知,并且始终发送至少一次。

如果您只需要获取一次状态,则可以在处理通知的方法中从通知中心取消注册FirstViewController - 来自所有通知:

[[NSNotificationCenter defaultCenter] removeObserver:self];

或特定通知:

[[NSNotificationCenter defaultCenter] removeObserver:self name:AFNetworkingReachabilityDidChangeNotification object:nil];

答案 1 :(得分:1)

我找到了一个简单的补丁,是的,它应该像魅力一样,而我找不到合理的解决方案来解决这个问题。

  1. 我在BOOL AppDelegate.h
  2. 中取了BOOL isCalledOnce;
    1. 在(AppDelegate.m
    2. 中添加了以下两种方法
      - (void) setAppRequestCallOnce {
         isCalledOnce = YES;
      }
      
       - (BOOL) checkAppRequestCalledOnce {
          return isCalledOnce;
       }
      

      1. 在可达性检查中,我提出了这样的条件,
      2. - (BOOL) connected {
            if(![self checkAppRequestCalledOnce]) {
                [self setAppRequestCallOnce];
                return YES;
            }
            return [AFNetworkReachabilityManager sharedManager].reachable;
        }
        

        <强>结论:

        当我检查可达性时来自FirstViewController,类似

        if(![delegateObj connected]) {
            //show no internet message
        }
        

        这将首先调用checkAppRequestCalledOnce方法,该方法返回isCalledOnce,如果其NO,则我将其设置为YES并返回YES(这里我们不确定可达性的实际状态。从现在开始,当我再次检查可达性时,它不会检查上述情况并返回实际的可达性状态。

        为什么我正在使用,因为即使开始时没有互联网可用,AFNetworking也会给我们一个错误,尽管我们可以显示它,即使我们没有实际的可达性状态

        如果您发现更优雅的方式,请发帖或评论。

答案 2 :(得分:1)

我有类似的问题。似乎AFNetworking需要一点时间才能启动。如果你想在应用程序中检查互联网连接:didFinishLaunchingWithOptions:use:

Reachability *reach = [Reachability reachabilityForInternetConnection];

if (reach.currentReachabilityStatus != NotReachable) {
    //NSLog(@"internet available");
}

或在AFNetworking上设置块并等待它被调用:

[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
    if (status < ReachableViaWiFi) {
        // no connection
    } else {
        // connected
    }
}];

[[AFNetworkReachabilityManager sharedManager] startMonitoring];

答案 3 :(得分:0)

我也遇到过同样的问题。在那之后,我试图在调用网络服务时花费0.3秒的延迟,它解决了我的问题。

FirstViewController中调用网络服务之前,您可能会尝试延迟一些。因为AFNetworking需要时间来监控互联网状态,并且在AFNetworking获取互联网状态之前加载控制器。所以每次你都会得到AFNetworkReachabilityStatusNotReachable

FirstViewController中调用网络服务之前要稍等一些,这可能会解决您的问题。

答案 4 :(得分:0)

如果您networkReachabilityStatus检查AFNetworkReachabilityStatusUnknown,AFNetworking会告诉您尚未确定状态。因此,干净的方法只有在知道后才使用reachable状态。例如:

- (void)networkReachableWithCompletion:(CompletionBlock)_completion
{
    if (!_completion) return; //no point continuing

    if ([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus != AFNetworkReachabilityStatusUnknown) {
        _completion([NSNumber numberWithBool:[AFNetworkReachabilityManager sharedManager].reachable]);
    } else {
        [self performSelector:@selector(networkReachableWithCompletion:) withObject:_completion afterDelay:0.3];
    }
}