React-native: iOS: NetInfo.isConnected всегда возвращает false

Созданный на 6 июл. 2016  ·  139Комментарии  ·  Источник: facebook/react-native

В настоящее время я использую RN 0.28.0 ...

NetInfo.isConnected.fetch().then(isConnected => {
      // variable isConnected is always false
    });

Я бы сделал пиар, но я не умею писать код для iOS.

Help Wanted iOS Locked

Самый полезный комментарий

Согласно предложениям @ robertodias180, я подошел к оболочке для isConnected,
Вроде работает, но интересно, во всех ли случаях будет работать

export function isNetworkConnected() {
  if (Platform.OS === 'ios') {
    return new Promise(resolve => {
      const handleFirstConnectivityChangeIOS = isConnected => {
        NetInfo.isConnected.removeEventListener('change', handleFirstConnectivityChangeIOS);
        resolve(isConnected);
      };
      NetInfo.isConnected.addEventListener('change', handleFirstConnectivityChangeIOS);
    });
  }

  return NetInfo.isConnected.fetch();
}

Все 139 Комментарий

Я также могу воспроизвести это с помощью RN 0.29.0. Раньше я работал на версии 0.26.2, и она отлично с ней работала. Собираюсь попробовать собрать из исходников и отладить.

+1

Я уже сообщал об этой проблеме раньше: https://github.com/facebook/react-native/issues/8469

Быстрый обходной путь - добавить обработчик событий NetInfo.isConnected.addEventListener('change', Function.prototype)

+1 и такая же проблема с NetInfo.fetch (). Done () - всегда возвращает unknown

Я решил это так:

componentDidMount() {
  const dispatchConnected = isConnected => this.props.dispatch(setIsConnected(isConnected));

  NetInfo.isConnected.fetch().then().done(() => {
    NetInfo.isConnected.addEventListener('change', dispatchConnected);
  });
}

+1

мы нашли эту ошибку в 0.29.2 ..

мы нашли эту ошибку в 0.28

0.30.0 все еще не работает

Соответствующий код не изменился, поэтому понятно, что он все еще не работает.

Обратите внимание, что я ранее сообщал об ошибке здесь: https://github.com/facebook/react-native/issues/8469, где подробно описывается причина и прилагается образец кода. В связи с этим, я думаю, имеет смысл оставить это закрытым.

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

Я заметил ту же проблему сегодня

Я использую версию 0.30.0, и я тоже обнаружил эту ошибку.

та же проблема для меня, я использую [email protected], и выборка всегда возвращается неизвестно.

Но вместо этого мы можем использовать addEventListener.

NetInfo.addEventListener('change',
    (networkType)=> {
        this.setState({networkType})
    }
)

вместо:

NetInfo.fetch().done(
    (networkType)=> {
        this.setState({networkType})
    }
)

Ошибка @ facebook-github-bot

У меня проблема с версией 0.31, будет ли это исправлено?

то же, что и 0,32

@knowbody Как работает ваш сниппет? Мне нужно определить метод setIsConnected в моем классе или как глобальную функцию или что-то еще? Потому что на самом деле у меня есть ошибка, которая сказала Can't find variable: setIsConnected

@florentsorel, поэтому в моем проекте я использую redux для управления состоянием, а setIsConnected - это мой создатель действий, который выглядит примерно так:

actions/network.js

export const setIsConnected = (isConnected) => ({
  type: 'SET_IS_CONNECTED',
  isConnected
});

а затем у меня есть редуктор network :

reducers/network.js

const initialState = {
  isConnected: true
};

const network = (state = initialState, action) => {
  switch (action.type) {
    case 'SET_IS_CONNECTED':
      return {
        isConnected: action.isConnected
      };

    default:
      return state;
  }
}

export default network;

+1

У меня эта проблема с версией 0.34.1

Изменить: обновлено до v0.35.0 и та же проблема.

то же самое на v0.35.0

У меня такая же проблема с версией 0.36.0

Фрагмент @knowbody работает у меня в

@Dnld : @Ehesp говорит, что он работает на версии 036, а вы и еще 5 - нет? Разве это не решено в конце концов? У меня тоже были проблемы с 0.33, и я хотел бы обновиться. Благодарю.

Базовый код на самом деле не изменился, поэтому я был бы удивлен, если бы он был «исправлен».

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

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

На данный момент кажется, что это желаемое поведение, поэтому, возможно, требуется изменение документации. NetInfo.isConnected возвращает логическое значение, поэтому оно не означает, что состояние неизвестно и что оно не изменится, пока вы не добавите прослушиватель событий. В качестве альтернативы функцию можно изменить, чтобы она возвращала null или логическое значение.

В моих приложениях есть код, очень похожий на тот, что опубликовал @knowbody . Я вообще не называю NetInfo.isConnected.fetch() , потому что это бесполезно при запуске.

Я предполагаю, что подключение есть, добавляю слушателя, а затем состояние будет обновлено, когда состояние подключения больше не будет неизвестным.

0.34.1 все еще не работает

Та же проблема с RN 0.37.0

@ xing-zheng по какой-то причине ваше решение возвращает только «МОБИЛЬНЫЙ», даже когда я выключаю Wi-Fi на своем компьютере, что должно отражаться в моем эмуляторе. Есть идеи, почему?

componentDidMount() { NetInfo.addEventListener('change', (networkType)=> { this.setState({connected: networkType}) } ) }

Та же проблема с RN 0.38.0

то же самое и в 0.39

Когда я пробую решение addEventListener, NetInfo обнаруживает только одно или два изменения подключения. Например, если я начну с подключения, а затем отключу его, Netinfo обнаружит это, но если я снова подключусь, он не сможет определить, что я сейчас подключен. NetInfo выдает очень много ложных срабатываний в моем приложении, даже с обходным путем. Кто-нибудь еще испытывает то же самое?

Мне пришлось придумать странный обходной путь, чтобы решить эту проблему. Почему-то один метод работает на android, а другой на iOS. Исправить это было бы здорово.

function handleFirstConnectivityChange(isConnected) {
    if (!sConnected) {
     // do action
    } 
    NetInfo.isConnected.removeEventListener('change', handleFirstConnectivityChange);
}

if (Platform.OS === 'ios') {
    NetInfo.isConnected.addEventListener('change', handleFirstConnectivityChange); 
} else {
    NetInfo.isConnected.fetch().then(isConnected => {
    if (!sConnected) {
        // do action
    } 
}

@ robertodias180 не работает.

РН- 0,39+

function handleFirstConnectivityChange (isConnected) {
if (! sConnected) {
// делаем действие
}
NetInfo.isConnected.removeEventListener ('изменение', handleFirstConnectivityChange);
}

if (Platform.OS === 'ios') {
NetInfo.isConnected.addEventListener ('изменить', handleFirstConnectivityChange);
} else {
NetInfo.isConnected.fetch (). Then (isConnected => {
if (! sConnected) {
// делаем действие
}
}

Не могли бы вы мне помочь?

@imbudhiraja работает на любой из платформ?

Нет, он не работал ни на одной платформе

благодаря
Маниш Будхираджа

3 января 2017 г. в 20:12 «Роберто Диас» [email protected] написал:

@imbudhiraja https://github.com/imbudhiraja работает ли он на любом из
платформы?

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/facebook/react-native/issues/8615#issuecomment-270128504 ,
или отключить поток
https://github.com/notifications/unsubscribe-auth/AVTjXHSe8OcVq8fQ5XVk8hh9XXHfHFVZks5rOl5ggaJpZM4JGaBc
.

Похоже, это могут быть две проблемы:

  1. isConnected.fetch кажется неработающим на iOS - исправление должно быть простым. Обходной путь, опубликованный @ robertodias180, имеет смысл, потому что он запрашивает собственный код другим методом.
  2. Нестабильность NetInfo, описанная @Aristekrat . Это больше беспокоит - может ли кто-нибудь помочь предоставить подробный способ воспроизвести эту проблему? Тогда я смогу помочь исправить это.

RN 0.38.1 и ранее, iOS Simulator.

componentDidMount() {
    NetInfo.isConnected.fetch().then(this._handleConnectionInfoChange);
    NetInfo.isConnected.addEventListener(
        'change',
        this._handleConnectionInfoChange
    );
 }

 componentWillUnmount(){
     NetInfo.isConnected.removeEventListener(
        'change',
        this._handleConnectionInfoChange
    );
 }

_handleConnectionInfoChange(isConnected){
    this.props.connectActions.netInfo(isConnected);

    dbg('connected', isConnected);

};

Первоначальный NetInfo.isConnected.fetch().then(this._handleConnectionInfoChange); правильно извлекает текущий статус соединения. Однако последующие изменения состояния подключения не фиксируются EventListener.

У меня была эта проблема для многих версий RN.

@imbudhiraja В итоге я сменил код на что-то «чище». У меня есть утилита, в которой отображается текущее состояние сетевого подключения. Это работает на обеих платформах. I initializeConnection когда приложение открывается, а затем isConnected когда мне нужно. Обратите внимание, что может пройти некоторое время, пока NetInfo получит статус подключения при открытии приложения (особенно на Android). Я только что задержался до hasConnection !== null . Надеюсь, поможет

const hasConnection = null;

export const initializeConnection = () => {

  const dispatchConnected = isConnected => { hasConnection = isConnected; };

  NetInfo.isConnected.fetch().then().done(() => {
    NetInfo.isConnected.addEventListener('change', dispatchConnected);
  });

}

export const isConnected = () => {
  NetInfo.fetch().done((reach) => {
    console.log('Initial: ' + reach);
  });
  return hasConnection;
}

Пробовал что-то подобное, я продолжаю сталкиваться с ситуацией, когда eventListener не обнаруживает его, когда соединение возвращается (на симуляторе).

Перезагрузить приложение без подключения к Интернету => Обнаружено
Включите Интернет снова => НЕ обнаружен

Перезагрузить приложение с подключением к Интернету => Обнаружено
Отключить интернет => Обнаружено
Включите Интернет снова => НЕ обнаружен

<strong i="11">@autobind</strong>
export default class ConnectionToast extends React.Component {

    constructor(props){
        super(props);
    }

    componentDidMount() {
        NetInfo.isConnected.fetch()
            .then(this._handleConnectionInfoChange)
            .done(this._addListener);
     }

     componentWillUnmount(){
         this._removeListener();
     }

     _addListener(){
         NetInfo.isConnected.addEventListener(
             'change',
             this._handleConnectionInfoChange
         );
     }

     _removeListener(){
         NetInfo.isConnected.removeEventListener(
            'change',
            this._handleConnectionInfoChange
        );
     }

    _handleConnectionInfoChange(isConnected){
        this.props.connectActions.netInfo(isConnected);

        dbg('connected', isConnected);

        // this._removeListener();
        // this._addListener();

    }

[...]

Пробовал удалять и повторно добавлять слушателя при каждом изменении, но без радости.

@mschipperheyn Я испытываю ту же проблему, используя подход, опубликованный ранее @knowbody .

Документы также подразумевают, что он будет обрабатывать только первое изменение через handleFirstConnectivityChange . Это правильно, или он должен обнаруживать все последующие изменения?

Убедитесь, что у вас есть

установить в вашем файле манифеста Android. Это меня сбило с толку.

Та же проблема с RN 0.41.0

в iOS не добавляйте слушателя и не регистрируйте SCNetworkReachabilitySetCallback. конечно не работает. какова цель дизайна?

то же, что и 0.41.2

@djohnkirby В вашем комментарии отсутствует XML, я думаю, вы хотели опубликовать - не могли бы вы отредактировать его, пожалуйста?

Строка, которую нужно добавить вам AndroidManifest.xml:

 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

0.39.2: Та же проблема. Не только NetInfo fetch result всегда false , но он также быстро обнаруживает изменение статуса соединения после запуска приложения.

0.42.0: Та же проблема. Я также описал здесь свою проблему: https://stackoverflow.com/questions/42642034/check-for-internet-connection-returns-wrong-results
Тестирую на iOS и macOS Sierra.

ОБНОВЛЕНИЕ : Моя проблема была из-за тестирования на симуляторе, на реальном устройстве все работает. Ответил в приведенной выше ссылке.

У меня такая же проблема :(

NetInfo.isConnected.fetch().then((isConnected) => { console.log(isConnected); });
// always return false

В случае, если кто-то хочет знать, работает ли приложение на симуляторе или нет: http://stackoverflow.com/a/34732015/552669

Это не ошибка. Собственный модуль RCTNetInfo является подклассом RCTEventEmitter , поэтому мы должны добавить наблюдателя для запуска метода startObserving .
В процессе запуска приложения добавьте в NetInfo произвольного наблюдателя, после чего вы можете вызвать функцию fetch . (NetInfo.isConnected действительно вызывает функцию выборки)

Согласно предложениям @ robertodias180, я подошел к оболочке для isConnected,
Вроде работает, но интересно, во всех ли случаях будет работать

export function isNetworkConnected() {
  if (Platform.OS === 'ios') {
    return new Promise(resolve => {
      const handleFirstConnectivityChangeIOS = isConnected => {
        NetInfo.isConnected.removeEventListener('change', handleFirstConnectivityChangeIOS);
        resolve(isConnected);
      };
      NetInfo.isConnected.addEventListener('change', handleFirstConnectivityChangeIOS);
    });
  }

  return NetInfo.isConnected.fetch();
}

Та же проблема. 0,40

У меня такая же проблема

0.42.3 - У меня @ Knight704 смягчило проблему.

То же самое с 0.42.3

то же самое на 0.43.1

Видя это на 0,40

с этой проблемой. Удалось заставить его работать случайным образом, после чего он перестал работать.

Решение @ Knight704 сначала работало для меня, но по какой-то причине, когда я вызываю его один раз изнутри второго уровня навигатора в модальном окне, функция перестает работать (handleFirstConnectivityChangeIOS никогда не вызывается), даже после того, как я закрываю модальное окно. Очень странное поведение, понятия не имею, почему это не работает или что-то еще в моей кодовой базе не работает с NetInfo.

что мне не хватает?

    this.state = {
            isConnected: null,
     }
    componentDidMount() {
        console.log('first one ', this.state.isConnected)
        NetInfo.isConnected.addEventListener(
            'change',
            this._handleConnectivityChange
        );
        console.log('second ', this.state.isConnected)
        NetInfo.isConnected.fetch().done(
            (isConnected) => {this.setState({isConnected});}
        );
        console.log('third ', this.state.isConnected)
    }
    componentWillUnmount(){
        console.log('did it unmount ', this.state.isConnected)
        NetInfo.isConnected.removeEventListener(
            'change',
            this._handleConnectionInfoChange
        );
        console.log('it did unmount ', this.state.isConnected)
    }
    _handleConnectivityChange = (isConnected) => {
        this.setState({
            isConnected,
        });
    };
   render() {
      console.log('fourth ', this.state.isConnected)
        if(this.state.isConnected === false){
            const connectAlert = (Alert.alert(
                'ERROR',
                'No connection bro!',
                [
                    {text: 'OK'},
                ]
            ))
        }
        return ()
}

поэтому, когда я запускаю его, он иногда предупреждает меня, а не всегда ....

это журналы консоли, возвращаемые, когда он дает мне предупреждение, даже когда есть соединение:

'fourth ', null
'first one ', null
'second ', null
'third ', null
'fourth ', false
'fourth ', true

Испытываю ту же проблему, что и @SteffeyDev, когда я использую исправление от @ Knight704 в https://github.com/facebook/react-native/issues/8615#issuecomment -287977178 В большинстве случаев это работает нормально, однако, когда у меня есть один и тот же код никогда не разрешится, поскольку я предполагаю, что событие change уже было отправлено.

Я заметил, что в этих условиях NetInfo.fetch() вернет состояние unknown (это вызовет false под NetInfo.isConnected.fetch() и поэтому я смог обойти это со следующей модификацией исходного решения:

export function isNetworkConnected() {
  return NetInfo.fetch().then(reachability => {
    if (reachability === 'unknown') {
      return new Promise(resolve => {
        const handleFirstConnectivityChangeIOS = isConnected => {
          NetInfo.isConnected.removeEventListener('change', handleFirstConnectivityChangeIOS);
          resolve(isConnected);
        };
        NetInfo.isConnected.addEventListener('change', handleFirstConnectivityChangeIOS);
      });
    }
    reachability = reachability.toLowerCase();
    return (reachability !== 'none' && reachability !== 'unknown');
  });
}

Условие unknown запускается только на iOS, поскольку Android возвращает UNKNOWN . Это также причина использования нижнего регистра перед возвратом статуса, поскольку это должно более или менее сохранить существующее поведение из NetInfo.isConnected.fetch .

то же самое в 0.44

Сначала я заметил, что NetInfo хочет вернуть изменение статуса сети только после одного цикла (включено -> выключено). Оказалось, что эта проблема есть только в симуляторе. На реальном устройстве он правильно запускает обратный вызов даже для нескольких циклов подключения / отключения.

Образец кода

  NetInfo.addEventListener( 'change', this._onConnectivityChange );

  _onConnectivityChange(connType) {
    // Do something with connType...
  }

Эта проблема некоторое время беспокоила меня, и я косвенно закончил тем, что создал небольшую служебную библиотеку, ориентированную на обнаружение RN в автономном / онлайн-режиме, охватывающую типичные шаблоны React и хорошую интеграцию с redux.

Он корректно работает на реальных устройствах, как Android, так и iOS. Однако я также могу подтвердить, что иногда прослушиватель не запускается в симуляторе iOS, и состояние подключения становится непоследовательным. Я еще не пробовал решения, предложенные @ knight704 и @Ignigena ( здесь и здесь соответственно), но, вероятно, скоро опробую их, когда у меня будет время.

PR также очень приветствуется в случае, если больше людей подтвердят, что эти решения работают как шарм!

Пожалуйста исправьте.

Если это вряд ли скоро будет исправлено, можем ли мы хотя бы обновить документы, чтобы указать, что это не работает в iOS?

@ jpb12 может стоит сделать пиар и посмотреть, объединят ли они это. Может на самом деле сделать это более заметным, поскольку кажется, что о нем забыли.

Я столкнулся с этой проблемой в версии для Android. Похоже, это связано с переходом на задний план и возвращением на передний план. К сожалению, я не могу достоверно воспроизвести эту проблему, но это определенно происходит после нескольких переходов фон / передний план. Особенно, если в этот раз статус подключения был изменен

Когда это произойдет
NetInfo.isConnected.fetch().then(isConnected => {...}) всегда возвращает false
NetInfo.fetch().then((reach) => {...}) всегда возвращает NONE
добавление / удаление слушателей не помогает

Буду очень признателен за любой надежный способ определения реального статуса подключения

Я столкнулся со странным поведением, потому что isConnected возвращает true при подключении к Wi-Fi (пока все в порядке), но если модем не подключается к Интернету, isConnected по-прежнему остается истинным. Я не совсем уверен, как эффективно проверить подключение к Интернету, а не только подключение к сети. Есть идеи? благодаря

@kodatech Этот модуль должен помочь вам решить эту проблему. Я недавно использовал его в своем проекте и настоятельно рекомендую https://github.com/rauliyohmc/react-native-offline

Большое спасибо @craigcoles

@ Knight704, спасибо, братан.

@craigcoles У вас есть рабочий код, которому я мог бы следовать?

@nmfzone У меня нет ничего, что я могу вам показать, но в Readme есть много примеров кода 😃

Я использую события прослушивателя Netinfo следующим образом, он отлично работает на обеих платформах.
"react-native": "0.43.4",

componentDidMount(){
        NetInfo.isConnected.addEventListener('change', this._handleConnectivityChange);

    }

    componentWillUnmount(){
        NetInfo.isConnected.removeEventListener('change', this._handleConnectivityChange);
    }

    _handleConnectivityChange = (isConnected) => {
         console.warn(isConnected);
    }

@ sumesh1993 По моему опыту, если приложение Android было свернуто (в фоновом режиме), оно не реагирует на событие 'change' . Проверено на моем Galaxy Note 5, Android 7.0

Модуль https://github.com/rauliyohmc/react-native-offline, который был рекомендован выше, просто непрерывно пингует https://google.com . Это работает, но я бы предпочел исправить эту ошибку

Это имеет смысл, поскольку приложения Android приостанавливаются в фоновом режиме. Чтобы получать события, вам нужно создать службу, которая будет продолжать работать, даже если приложение приостановлено.

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

@ alsh76 для меня он работает, когда приложение находится в фоновом режиме, он не работает, когда приложение убито из меню многозадачности.
Я решил это, вызывая следующую функцию всякий раз, когда мой домашний экран запускается.
if(Platform.OS === 'android'){ NetInfo.isConnected.fetch().then(isConnected => { if(!isConnected) return; //Do something }); }

Встретил ту же проблему с виртуальным устройством Android. Но дело в том, что несколько дней назад все было хорошо, но на устройстве iOS и в эмуляторе все еще происходит. Кто-нибудь нашел стабильный и правильный способ узнать статус сетевого подключения?

Спасибо @ sumesh1993, который
@igorarkhipenko пробовали его предложение?

Привет, вы добавили разрешение, например, Android нужно добавить
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

просто небольшое обновление решений @ Knight704 и @Ignigena, поскольку NetInfo.fetch теперь устарел. Это помогло мне:
``
const isNetworkConnected = () => {
return NetInfo.getConnectionInfo (). then (reachability => {
if (reachability.type === 'unknown') {
вернуть новое обещание (resolve => {
const handleFirstConnectivityChangeIOS = isConnected => {
NetInfo.isConnected.removeEventListener ('connectionChange', handleFirstConnectivityChangeIOS);
решить (isConnected);
};
NetInfo.isConnected.addEventListener ('connectionChange', handleFirstConnectivityChangeIOS);
});
}
return (reachability.type! == 'none' && reachability.type! == 'unknown')
});
}

Имхо NetInfo.isConnected.fetch() - важная функция, и ее нужно исправить как можно скорее!

@javache @sahrens @davidaurelio @janicduplessis @hramos @shergin @rigdern есть ли сроки для этого?

Спасибо!

@pensierinmusica Это проект, управляемый сообществом, поэтому я хотел бы получить хороший пиар.

@shergin Я думал, что React Native был создан, поддерживается и используется внутри Facebook и по этой причине выпущен под лицензией BSD с тремя

cc @rigdern

Большое количество кода ядра RN написано и поддерживается сообществом.

И есть много функций и функций, не используемых Facebook, поэтому нам сложно расставить приоритеты и отдать предпочтение PR сообщества, где автор может проверить исправление своей ошибки / варианта использования.

У меня также возникла проблема с реакцией 0.47.0 с ios.

@pensierinmusica, эта проблема должна быть определенно приоритетной. Насколько сложно получить логический возврат из .isConnected ()?

Хорошо, вот обходной путь из коробки, который должен помочь (ну, он подходит для меня). Я отправляю http-запрос на сайт, который, как я знаю, будет активен, и оцениваю ответ.

Я инициализировал репо, которое должно работать из коробки. https://github.com/JamesDorrian/NetInfoCheckConnection/tree/master

Примечание. Обязательно измените переменную httpAddress с https://www.galwaydaily.com на что-то другое (возможно, google.com), поскольку я не могу гарантировать, что она всегда будет работать. Я надеюсь, что это поможет всем, кто разочарован NetInfo!

@pensierinmusica @anujsinghwd

@JamesDorrian, спасибо, в итоге я сделал что-то подобное, пингуя "google.com".

Вот фрагмент:

// /utilities/connectivity.js

import { Alert } from 'react-native';

export function warning () {
  Alert.alert(
    'No connection',
    'Mmm... you seem to be offline'
  );
};

export async function checkAsync () {
  try {
    const res = await fetch('https://google.com');
    if (res.status === 200) return true;
  } catch (e) {
    warning();
  }
  return false;
};

Тем не менее, это всего лишь временный обходной путь, и я думаю, что NetInfo.isConnected следует исправить как можно скорее!

let isConnected = false;

Platform.OS === "ios" 
  ? (isConnected = await fetch("https://www.google.com"))
  : (isConnected = await NetInfo.isConnected.fetch());

Platform.OS === "ios" && (isConnected.status = 200)
  ? (isConnected = true)
  : (isConnected = false);

console.log(isConnected); //Result

Можем ли мы остановиться на +1 комментариях по этой проблеме, пожалуйста, для этого используются реакции.

iOS:
первый запрос. в случае сбоя сервера в телефоне есть Wi-Fi.
NetInfo.isConnected.fetch (). Then ((isConnected) => {всегда ложно}
0.49.3.

@kddc, кажется, ваше решение работает нормально в разработке 👍

Просто добавьте библиотеку Reachability Library в свой проект XCode от Apple, который здесь служил, это решение.

@fuatsengul Я добавил проект

Проблема, по-видимому, связана только с api fetch ... однако добавление прослушивателя событий работает на iOS .. Однако addEventListener не работает на android, поэтому вам нужно использовать fetch api :)

Вот мой фрагмент, чтобы заставить его работать в обоих мирах:

function handleFirstConnectivityChange(isConnected) {
  console.log('Then, is ' + (isConnected ? 'online' : 'offline'))
  NetInfo.isConnected.removeEventListener(
    'connectionChange',
    handleFirstConnectivityChange,
  )
}

if (Platform.OS === 'android') {
    NetInfo.isConnected.fetch().then(isConnected => {
      console.log('First, is ' + (isConnected ? 'online' : 'offline'))
    })
  } else {
    NetInfo.isConnected.addEventListener(
      'connectionChange',
      handleFirstConnectivityChange,
    )
  }

Он отображается в автономном режиме в IOS, хотя он подключен
РН - 0,50

NetInfo.isConnected.fetch().then(isConnected => { console.log('First, is ' + (isConnected ? 'online' : 'offline')); });

@kddc спасибо за обходной путь.
Я столкнулся с проблемой на моем устройстве iOS, и сценарий выглядит следующим образом:

  1. ios -> режим полета включен
  2. выполнить выборку -> получение 'сетевой ошибки', isConnected - false, а reachability.type - none
  3. ios -> режим полета выключен
  4. выполнить выборку -> получить 'ошибку сети', isConnected имеет значение false, а reachability.type - none

Все время, пока приложение работает, в фоновом режиме при изменении режима полета.
Только перезапуск приложения «ловит» новое сетевое соединение.

+1

+1

Спасибо за исправление @ alburdette619
Итак, это исправлено, и будет ли это доступно в версии 0.54?

@ assafb81 Я не уверен, очевидно, они приземляются внутри, и я не уверен, что это за процесс, а вы?

Когда ваш пул-реквест объединяется, Facebook сначала включает его в свое внутреннее репозиторий React Native и, помимо прочего, выполняет дополнительные тесты. Когда это удастся, изменение экспортируется обратно в репозиторий GitHub.

Посмотрев на активность вашего запроса на перенос, вы увидите, что ваш коммит теперь объединен на GitHub . Просматривая информацию о фиксации, вы можете увидеть, в какие ветки она включена. В настоящее время она находится только в «главной» ветке:

image

Для сравнения, если вы посмотрите на более старую фиксацию, вы увидите, что она появляется в нескольких ветках:

image

В начале каждого месяца на основе «master» создается новая ветка кандидата на выпуск. Так что ваше изменение, скорее всего, будет в следующем выпуске-кандидате в начале марта. Вы можете узнать больше о графике выпуска React Native в этом сообщении в блоге .

Адам Комелла
Microsoft Corp.

Кто-нибудь проверял эту проблему с последней версией RN 54? Для меня он всегда возвращает «истина» сейчас на iOS, а на Android работает отлично. Кто-нибудь еще видит эту проблему?

0.53 всегда ложно .. @deepaksasken .. кажется, мне нужно отключить код только для Android .. Не могу использовать 0.54 для многих ошибок.

@ alien3d Вы имеете в виду отключить его для iOS и оставить только для Android? В Андроиде работает?

@afilp, я просто следую приведенному выше примеру для ios

    if (Platform.OS === "ios") {
            isConnected = await fetch("https://www.google.com");
            if (isConnected) { }
  } else { 
    NetInfo.isConnected.fetch().done(
                (isConnected) => {
                    if (isConnected) { }
} 

Мне все еще нужно много тестов, прежде чем я буду считать его стабильным. сейчас использую назад 0,530

@ assafb81 Нашли решение проблемы с авиарежимом? Я использую ваше решение в 0.53.

@aflip Когда данные включены, но пакета нет, он возвращает isConnected true. Вы пытались решить это?

Почему существует removeEventListener. Разве приложение не должно постоянно отслеживать сетевые изменения. Кто угодно?

Также возникает та же проблема, что и у пользователей выше. Слушатели событий NetInfo кажутся очень ненадежными. Я пробовал многие из вышеперечисленных обходных решений без стабильных результатов. На данный момент я буду полагаться на получение https://google.com или конечную точку работоспособности на моих собственных серверах, чтобы у моих пользователей было подключение к Интернету.

@MichaelPintos У меня работает, спасибо.

РН 0,54,2
ОС: iOS
та же проблема, всегда неизвестно

Когда я обновляю RN до 0.55.3

Я использую этот код, сначала возвращаю неизвестно, а потом он работает

    NetInfo.getConnectionInfo()
        .then()
        .done(() => {
                switch (connectionInfo.type) {
                    case 'none':
                        Alert.alert('aa', 'none');
                        break;
                    case 'wifi':
                        Alert.alert('aa', 'wifi');
                        break;
                    case 'cellular':
                        if (connectionInfo.effectiveType !== 'unknown') {
                            Alert.alert('aa', `cellular ${connectionInfo.effectiveType}`);
                        } else {
                            Alert.alert('aa', 'cellular unknown');
                        }
                        break;
                    case 'unknown':
                        Alert.alert('aa', 'unknown');
                        break;
                    default:
                        Alert.alert('aa', 'default');
                        break;
                }
            });
        });

Хорошо, давайте сделаем небольшой трюк.

    NetInfo.getConnectionInfo()
        .then()
        .done(() => {
            NetInfo.getConnectionInfo().then(connectionInfo => {
                switch (connectionInfo.type) {
                    case 'none':
                        Alert.alert('aa', 'none');
                        break;
                    case 'wifi':
                        Alert.alert('aa', 'wifi');
                        break;
                    case 'cellular':
                        if (connectionInfo.effectiveType !== 'unknown') {
                            Alert.alert('aa', `cellular ${connectionInfo.effectiveType}`);
                        } else {
                            Alert.alert('aa', 'cellular unknown');
                        }
                        break;
                    case 'unknown':
                        Alert.alert('aa', 'unknown');
                        break;
                    default:
                        Alert.alert('aa', 'default');
                        break;
                }
            });
        });

Это мое решение. Ожидайте официального решения.

Обновлен до 55 специально, потому что в журнале изменений сказано, что это должно исправить - все еще не работает (0.55.3).

Я могу заставить его работать, используя решение, аналогичное @ yuyao110120 :

NetInfo.isConnected.fetch().then(() => {
  NetInfo.isConnected.fetch().then(isConnected =>
    // isConnected is now the correct value
  });
});

Я больше не доверяю NetInfo (react-native 0.53.3)
Вот что я делаю, чтобы убедиться, что есть интернет:

async function handleConnectivityChange(status) {
  const { type } = status;
  let probablyHasInternet;
  try {
    const googleCall = await fetch(
        'https://google.com', {
        headers: {
          'Cache-Control': 'no-cache, no-store, must-revalidate',
          Pragma: 'no-cache',
          Expires: 0,
        },
      });
    probablyHasInternet = googleCall.status === 200;
  } catch (e) {
    probablyHasInternet = false;
  }

  console.log(`@@ isConnected: ${probablyHasInternet}`);

}

  NetInfo.getConnectionInfo().then(handleConnectivityChange);
  NetInfo.addEventListener('connectionChange', handleConnectivityChange);

@SudoPlz Я сделал то же самое в своих приложениях, работает нормально. Но NetInfo API должен быть исправлен, ха-ха!

@SudoPlz Я заметил, что fetch кеширует запрос на Android. Чтобы этого не произошло, вам нужно будет указать несколько заголовков.

      const googleRequest = await fetch('https://www.google.com', {
        headers: {
          'Cache-Control': 'no-cache, no-store, must-revalidate',
          'Pragma': 'no-cache',
          'Expires': 0
        }
      });

Хорошо, спасибо, что сообщили мне

то же, что и @kylevdr , работал надежно, но добавление небольшого тайм-аута перед 2-м вызовом, похоже, помогает с мерцанием, когда он отключается на разделение 2-го сразу после разблокировки

Изменить: fwiw это работает в 55.3, но не в 55.4

Добавление прослушивателя событий начального подключения приведет к правильной работе NetInfo.getConnectionInfo() и NetInfo.isConnected.fetch() при первом вызове.

const onInitialNetConnection = isConnected => {
    console.log(`Is initially connected: ${isConnected}`);

    NetInfo.isConnected.removeEventListener(
        onInitialNetConnection
    );
};

NetInfo.isConnected.addEventListener(
    'connectionChange',
    onInitialNetConnection
);

// both now work on the first call.
await NetInfo.getConnectionInfo();
await NetInfo.isConnected.fetch();

Спасибо # 8469

Обязательно импортируйте этот файл, иначе он не будет выполнен.

PS Если вы используете fetch , используйте method: 'HEAD' чтобы уменьшить объем передаваемых данных.

Ни одно из вышеперечисленных решений не сработало при запуске приложения в режиме отладки на iPhone 8 (React Native 0.55.3, iOS 11.3.1) в следующем сценарии: Закройте приложение и запустите его с отключенными мобильными данными и Wi-Fi.

Любые последующие события теряются со всеми упомянутыми выше решениями (за исключением ответа @SudoPlz ). Только запуск приложения в режиме выпуска на устройстве или в режиме отладки на симуляторе запускал любые события NetInfo .

@nlindroos, так вы действительно подтверждаете, что NetInfo отлично работает на устройствах, на которых установлена ​​окончательная версия?

В конкретном случае _запуска_ приложения в автономном режиме на физическом устройстве iOS, запуск в режиме выпуска был единственным рабочим решением для запуска любых событий NetInfo . Я не тестировал все связанные сценарии в достаточной степени, чтобы поручиться за это как за универсальное решение всех проблем NetInfo .

Могу сказать, что комбинация решений, которые @woodpav и @AbdallaMohamed сработали для меня
Я использую RN версии 0.55.4

Я должен часто пинговать сервер Google, чтобы проверить подключение к Интернету 😕

Я использую симулятор iPhone 8-11.3 и NetInfo.isConnected.fetch () в версии 0.55.4 RN. Then (isConnected => console.log ('isConnected', isConnected))
Всегда возвращает false. Это проблема и при производстве на телефоне. Пробовал варианты мобильных данных и Wi-Fi.

При переходе на RN версии 0.55.3 вроде снова работает.

@octopitus , @martinentelect
это мой код, я использую собственную версию реакции 0.55.4, и это разумный и рабочий обходной путь, пока не будет исправлено NetInfo .
В моем файле api.js у меня есть этот код

import { NetInfo } from 'react-native';
import { url } from '[AppName]/src/config';

export const onInitialNetConnection = () => {
    NetInfo.isConnected.removeEventListener(onInitialNetConnection);
};

const getDataById = async (dataId) => {
    // both now work on the first call.
    await NetInfo.getConnectionInfo();
    const isConnected = await NetInfo.isConnected.fetch();
    if (!isConnected) {
        throw new Error('networkError');
    }
    const response = await fetch(`${url}${dataId}`, {
        headers: {
            'Cache-Control': 'no-cache, no-store, must-revalidate',
            Pragma: 'no-cache',
            Expires: 0,
        },
    });
    if (response.ok) {
        return response.json();
    }
    throw new Error('invalidCode');
};

export default getDataById;

В моем файле App.js (моя точка входа в приложение) я добавляю прослушиватель событий:

NetInfo.isConnected.addEventListener(
            'connectionChange',
            onInitialNetConnection,
        );

@ assafb81 Спасибо! Это помогло моему варианту использования.

В моем случае прослушиватель событий отлично работает на iOS, но никак не на Android (по крайней мере, на эмуляторе).
Есть ли обходные пути для слушателей на Android, которые все еще используют NetInfo?

    NetInfo.isConnected.addEventListener(
      "connectionChange",
      this.handleConnectionChange
    ); 

Использовать


this.count = 0
handleConnectivityChange(isConnected) {
   //for iOS
    this.count++
  console.log(isConnected + "isConnected")
  if(this.count > 1){
    console.log(isConnected + "this is the right value")
  }

@tannera ,
проверьте на реальном устройстве Android, а не на эмуляторе

На 0.55.4 это все еще ошибка, и я только что попал в продакшн 😢

По-прежнему не исправлен на 0.56

@SudoPlz Я скрыл ваш комментарий в ветке обсуждения 0.57 как не по теме. Как вы знаете, в репо есть сотни открытых проблем, но эта ветка ориентирована на выпуск версии 0.57.

Эта ветка в закрытом режиме практически невидима для сопровождающих, и я удивлен, что через шесть месяцев после появления потенциального исправления никто не открыл новую проблему. Если это то, что вы хотели бы исправить в мастере, пожалуйста, откройте новую проблему с подробностями и, в идеале, отправьте PR.

Вот минимальный воспроизводимый пример (протестирован на устройстве iOS) с некоторым кодом из @woodpav, опубликованным выше, для решения проблемы, закомментированным вверху: https://snack.expo.io/@notbrent/netinfo -repro.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги