Подтвердить что ты не робот

Доступность AFNetworking 2.0

Я пытаюсь определить, подключен ли пользователь к Интернету с помощью AFNetworking 2.0 и "AFNetworkReachabilityManager", но он, похоже, не работает. Всегда возвращается, что есть действующее подключение к Интернету, хотя интернет отключен. Это мой код:

 -(BOOL)connected {

   __block BOOL reachable;

    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {

        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;

                [[AFNetworkReachabilityManager sharedManager] startMonitoring];
        }
    }];

    return reachable;

}

Этот метод вызывается из моего метода viewDidLoad. Что-то не так с моим кодом, так как оно не работает?

4b9b3361

Ответ 1

Это потому, что этот блок выполняется только тогда, когда достижимость изменяет.

Чтобы получить текущий статус, вы можете сделать это:

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

Ответ 2

Вы делаете это сложнее, чем нужно. Попробуйте следующее:

- (void)viewDidLoad {
   [super viewDidLoad];

   [[AFNetworkReachabilityManager sharedManager] startMonitoring];

}

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

Если вы также хотите получать уведомления о статусе изменений, тогда выполните setReachabilityStatusChangeBlock

Надеюсь, это поможет!

Ответ 3

У вас есть две ошибки кода, которые предотвратят работу вашего кода.

Во-первых, ваш вызов "начать мониторинг" происходит внутри блока, который запускается в ответ на изменения достижимости, поэтому блок никогда не будет срабатывать (если вы не начнете мониторинг в другом месте).

Во-вторых, нет гарантии того, когда этот блок сработает. В результате вы всегда будете видеть, что "достижимый" возвращает любое значение, которое было инициализировано, видимо, это обычно равно нулю. Даже если вы исправите первую ошибку, нет гарантии (и это действительно маловероятно), что блок будет срабатывать, прежде чем вы вернетесь.

Наконец, на более общем уровне вы также пытаетесь протестировать синхронный код, который может выполняться только асинхронно. То есть невозможно, чтобы менеджер достижимости точно определял достижимость мгновенно. Он может сказать: "Я думаю, что я нахожусь в WiFi" или "Я думаю, что я нахожусь на 3G", но также нужно проверить, действительно ли он может достичь интернета (отсюда и вероятность достижимости имени), прежде чем это станет возможно. Достижимость - это не только "У меня есть Wi-Fi" или "У меня есть 3g" соединение, но и о том, можете ли вы добраться до него через Интернет. Это означает, что на самом деле устройство должно отправить запрос, и хотя это можно технически выполнить синхронно, каждое отдельное правило в книге настаивает на том, что сетевой код должен выполняться асинхронно и не без оснований. Если вы сделали это синхронно, вы заблокировали бы свой пользовательский интерфейс до тех пор, пока сетевой вызов не вернется... возможно, 30, 40, 50, даже 60 секунд спустя, в зависимости от соответствующих тайм-аутов.

Что вам нужно сделать, так это запустить мониторинг Singleton в своем приложении, выполнив загрузку метода делегата приложения, а затем извлеките его позже. Не зная структуры вашего приложения, я даже не буду пытаться гарантировать точность, но это должно хотя бы немного помочь.

Ответ 4

Попробуйте это,

В приложении AppDelegate, didFinishLaunchingWithOptions

{ // SETUP AFNETWORKING NETWORK INDICATOR AND REACHABILITY
    [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
}

В классе HttpManager,

- (BOOL)isNetworkRechable {

    if ([AFNetworkReachabilityManager sharedManager].reachable) {

        if ([AFNetworkReachabilityManager sharedManager].isReachableViaWiFi)
            NSLog(@"Network reachable via WWAN");
        else
            NSLog(@"Network reachable via Wifi");

        return YES;
    }
    else {

        NSLog(@"Network is not reachable");
        return NO;
    }
}

В yourViewController,

[[HttpManager sharedObject] isNetworkRechable];

Примечание. Не проверяйте networkRechability в первую очередь. Потому что это не сработает. Поэтому, пожалуйста, подождите минимум 1 сек, чтобы проверить его.

Ответ 5

Согласно моему опыту,

[[AFNetworkReachabilityManager sharedManager] startMonitoring];

требуется момент для выполнения setReachabilityStatusChangeBlock, поэтому нет значения возвращаемого значения из -(BOOL)connected.

Итак, вы можете выполнить некоторую задачу, когда сеть подключена/отключена.

Следующая функция лучше всего проверить связь на месте (синхронно):

[AFNetworkReachabilityManager sharedManager].reachable;

Ответ 6

Другие ответы неверны! Лучше использовать это, чтобы проверить наличие:

if ([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus == AFNetworkReachabilityStatusNotReachable)

Причина в том, что изначально networkReachabilityStatus будет установлен в AFNetworkReachabilityStatusUnknown до тех пор, пока не будет вызван блок состояния изменения, и это перестанет думать, что сеть недоступна, когда это не так.

Ответ 7

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    [self checkNetworkReachability];
}    


+(BOOL) isReachable{
   return [AFNetworkReachabilityManager sharedManager].reachable;
}

+(void) checkNetworkReachability{
        [[AFNetworkReachabilityManager sharedManager] startMonitoring];
        [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status));

            // Check the reachability status and show an alert if the internet connection is not available
            switch (status) {
                case -1:
                    // AFNetworkReachabilityStatusUnknown = -1,
                    NSLog(@"The reachability status is Unknown");
                    break;
                case 0:
                    // AFNetworkReachabilityStatusNotReachable = 0
                    NSLog(@"The reachability status is not reachable");
                    break;
                case 1:
                    NSLog(@"The reachability status is reachable via wan");
                    [[NSNotificationCenter defaultCenter] postNotificationName:@"Network_Reachable" object:nil];
                    break;
                case 2:
                    // AFNetworkReachabilityStatusReachableViaWiFi = 2
                    NSLog(@"The reachability status is reachable via WiFi");

                    [[NSNotificationCenter defaultCenter] postNotificationName:@"Network_Reachable" object:nil];
                    break;

                default:
                    break;
            }

        }];
    }