Досягаемость не работает при подключении Wi-Fi, но нет интернета

Я использую код достижимости Apple и устанавливаю как начальные уведомления о том, когда изменяется доступность сети, так и до начала подключения к серверу. Код работает, когда я нахожусь в wi-fi, и я отключу точку доступа Wi-Fi. Однако, когда я запускаю приложение с wi-fi и базовым широкополосным подключением, а затем после запуска приложения, а затем отключает Wi-Fi-маршрутизатор от широкополосного маршрутизатора (например, Wi-Fi включен, но нет Интернета подключение), и я выполняю проверку доступности, статус сети, которую я получаю, - это ReachableViaWiFi. Я пробовал как достижимостьForInternetConnection и достижимостьWithHostName.

Любые идеи о том, можно ли использовать код достижимости Apple для обнаружения ситуации, когда Wi-Fi подключен, но нет базовой сетевой связи?

Спасибо!

Ответ 1

ok, я узнал ответ на этот вопрос: доступность Apple не проверяет фактическую связь с хостом. См. Ответ @Zhami в ссылке SO ниже:

Как написать простой метод Ping в Cocoa/Objective-C

По сути, когда вы впервые запускаете приложение и выполняете проверку на доступность, iOS, похоже, выполняет поиск DNS, и если нет Интернета, проверка не выполняется. Таким образом, в первый раз, когда вы проверяете доступность, он фактически возвращает значимое значение. Однако, если вы подключены к запуску приложения и через некоторое время потеряете подключение к Интернету (при этом все еще подключены к Wi-Fi/3G/4G, но не имеют базового подключения к Интернету), дальнейшие проверки доступности достижимы, даже если интернет или ваш указанный хост недоступны больше.

Итак, если вы действительно хотите проверить подключение в режиме реального времени, подумайте о следующем:

-(BOOL) isConnected
{

    NSString* url = [NSURL URLWithString:@"http://www.google.com/m"];
    ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]];
    [request    setTimeOutSeconds:10];
//customize as per your needs - note this check is synchronous so you dont want to block the main thread for too long
    [request setNumberOfTimesToRetryOnTimeout:0];
    [request startSynchronous];

    NSError *error = [request error];
    if (error)
    {
        DLog(@"connectivity error");
        return NO;
    }
    else
    {
        DLog(@"connectivity OK");
        return YES;
    }

}

Ответ 2

Это очень старый пост, но он может остаться здесь для справки. В классе примера достижимости вы можете найти следующий код:

- (BOOL)startNotifier  
{  
    BOOL returnValue = NO;
    SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};

   if (SCNetworkReachabilitySetCallback(_reachabilityRef, ReachabilityCallback, &context))
   {
        if (SCNetworkReachabilityScheduleWithRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))
        {
            returnValue = YES;
        }
   }

   return returnValue;
}

Это приведет к изменению вашей _reachabilityRef изменений в сети.