Проверьте, доступен ли Inte rnet доступ - PullRequest
0 голосов
/ 08 января 2020

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

Примечание: Я подключен к точке WiFi, которая не есть Inte rnet

Я хочу проверить, доступен ли Inte rnet. Я попытался использовать Reachability, как описано здесь , и я также попробовал более простое решение, как описано здесь

Проблема в том, что с Reachability возвращается то, что Inte rnet достижимо, когда это не так. Другое решение занимает слишком много времени, чтобы дать ответ. Я попытался установить интервалы времени ожидания для запроса и сеанса, но он игнорируется.

Как проверить доступность inte rnet в случае, если я подключен к Wi-Fi без Inte rnet?

Вот код, который я использую:

- (void) postAsyncTaskWithUrl:(NSString*)urlString
                      andType:(NSString*)requestType
                     andToken:(NSString*)token
          andPropertiesObject:(id)propObject
                   urlEncoded:(BOOL)isUrlEncoded
                  withSuccess:(nullable void(^)(id _Nullable))success
                   andFailure:(nullable void(^)(id _Nullable))failure
{

    internetReachableFoo = [Reachability reachabilityWithHostname:@"www.google.com"];

    __weak typeof(self) weakSelf = self;
    // Internet is reachable
    internetReachableFoo.reachableBlock = ^(Reachability*reach)
    {
                 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlSt];
        [request setTimeoutInterval:20]; //Ignored ... WHY?

        NSURLSessionConfiguration *sessionConfigurations = [NSURLSessionConfiguration defaultSessionConfiguration];
        [sessionConfigurations setTimeoutIntervalForRequest:20]; //Ignored ... WHY?
        [sessionConfigurations setTimeoutIntervalForResource:20]; //Ignored ... WHY?
//        NSURLSession *session = [NSURLSession sharedSession];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfigurations];
        [[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {


     }

}

}

Ответы [ 3 ]

4 голосов
/ 08 января 2020

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

Согласно официальной документации Apple :

Всегда пытайтесь установить соединение. Не пытайтесь угадать, доступна ли сетевая служба, и не кэшируйте это определение

Подобное сообщение в блоге Джареда Синклера на эту топи c, используя SCNetworkReachability ( это то, что библиотека Reachability использует под капотом):

SCNetworkReachability следует использовать только для того, чтобы влиять на то, что вы делаете с сетевым запросом, который уже потерпел неудачу, а не с первоначальным запросом, который еще не был предпринят , Используйте отрицательный статус, чтобы определить, пытаетесь ли вы автоматически повторить попытку c или настроить язык оповещения, ориентированный на пользователя. Используйте положительный статус, чтобы попытаться повторить ранее неудачный запрос. Никогда не препятствуйте выполнению инициируемого пользователем запроса только потому, что SCNetworkReachability считает, что сеть недоступна

Заимствование из недавнего потока Reddit :

Достижимость - это одна или «эти темы» в мире iOS. Что значит, что Inte rnet достижимо? Даже если вы проверите сетевые интерфейсы, вы не сможете связаться с apple.com или google.com. Даже если вы подключитесь к Google, вы не сможете получить доступ к своему локальному серверу или облаку. Если вы проверите, можете ли вы добраться до интересующего вас сервера, почему бы не отправить запрос сразу?

2 голосов
/ 08 января 2020

TL; DR: Возможно, вам нужен NSTimer.

В моем приложении я хочу сделать сетевой вызов, только если у меня есть доступ к inte rnet.

Это не значимое утверждение. Нет никакого теста, который вы можете выполнить, который надежно означает, что вы можете «получить доступ к inte rnet» (несмотря на существование NSURLErrorNotConnectedToInte rnet, что на самом деле не означает, что он говорит). Например, ваш код пытается обработать «www.google.com» как «inte rnet». Но вполне возможно иметь сеть, которая разрешает пакеты от go до www.google.com, но нигде больше. Или разрешить пакеты ICMP, но не пакеты HTTP. Или разрешить HTTP-пакеты, но не на определенных портах. Такие конфигурации сети не просто возможны, они распространены, и по-разному все они могут выглядеть как «не на inte rnet».

Единственное, что вы можете ответить, это «могу я отправить пакет на указанный хост c и получить пакет взамен? " Даже невозможно узнать, можете ли вы просто отправить пакет. Если вы ничего не получите взамен, вы не знаете, был ли ваш пакет доставлен или нет.

Достижимость отвечает на вопрос: «Если я попытаюсь отправить пакет, попытается ли мой стек локальной сети даже попробовать? " Это в основном вопрос о том, есть ли первый прыжок, доступный в таблице маршрутизации. Это не значит, что вы можете подключиться; он может только сказать вам, что это абсолютно не так.

Используемые вами таймауты основаны на времени простоя сеанса. Но вы никогда не начинаете сеанс, поэтому он никогда не работает на холостом ходу. Время ожидания, которое вы ищете, - это время ожидания TCP, которое, как я ожидаю, составит 4 минуты. NSURLSession не может его настроить.

Если вам нужен тайм-аут «от начала до конца» настенных часов, то вам нужно запустить его самостоятельно с таймером .

0 голосов
/ 12 января 2020

Если вы попытаетесь загрузить http://captive.apple.com, он вернет жестко закодированную строку «Success» в качестве тела, если inte rnet работает или будет перенаправлять / не выполнять. Вы можете проверить, что ответ начинается с 200, а тело - «успех». Это то, что Apple использует для автоматического отображения окна учетных данных при подключении к аэропорту, как, например, Wi-Fi. Говорят, что а) нет надежного решения б) вы будете тратить данные пользователя (может быть, в вашем случае это нормально?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...