-1

我在我的应用程序中使用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 中,我正在调用网络请求,在此之前,我会检查互联网连接。这就是问题所在。每次,它都会向我展示No internetFirstViewController。因为,虽然它要求网络请求,AFNetworking但不要更新互联网的状态。更新可能需要几秒钟的摩擦,但更新速度不会那么快。因为,我知道这个问题,我不想应用补丁来解决这个问题。我尝试了不同的方法来解决这个问题。用过的,

sleep(2);在返回 YES 之前didFinishLaunchingWithOptions...

dispatch_synq- 冻结应用程序

dispatch_asynq- 不工作

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

4

5 回答 5

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];
于 2015-04-08T13:27:17.863 回答
1

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

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];
于 2015-02-18T15:48:09.493 回答
1

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

  1. 我参加BOOLAppDelegate.h BOOL isCalledOnce;

  1. AppDelegate.m在 ( )中添加了如下两个方法
- (void) setAppRequestCallOnce {
   isCalledOnce = YES;
}
 - (BOOL) checkAppRequestCalledOnce {
    return isCalledOnce;
 }

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

结论:

FirstViewController我检查可达性开始,例如,

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

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

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

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

于 2014-12-26T12:38:16.013 回答
0

我也遇到过同样的问题。之后,我尝试在调用 web 服务时延迟 0.3 秒,它解决了我的问题。

您可以尝试在调用 web-service 之前延迟一些时间FirstViewController。因为在获取 Internet 状态AFNetworking之前需要时间来监控 Internet 状态并且您的控制器会加载AFNetworking。所以每次你都会得到AFNetworkReachabilityStatusNotReachable

在调用 web-service 之前延迟一些时间FirstViewController,它可能会解决您的问题。

于 2014-12-26T12:01:12.327 回答
0

networkReachabilityStatus如果您检查.AFNetworking 会告诉您它尚未确定状态AFNetworkReachabilityStatusUnknown。因此,做到这一点的干净方法是只使用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];
    }
}
于 2015-11-14T20:17:13.743 回答