Skip to content

Commit bbf3723

Browse files
authored
Added possibility to configure NetInfo with an url to check connectivity (#426)
* Added possibility to configure NetInfo with an url to check connectivity * Fixed bug with NetInfo sending event before bridge ready
1 parent 5d42c8b commit bbf3723

File tree

4 files changed

+372
-59
lines changed

4 files changed

+372
-59
lines changed

Libraries/Network/NetInfo.desktop.js

+254
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
* @flow
9+
*/
10+
11+
'use strict';
12+
13+
const Map = require('Map');
14+
const NativeEventEmitter = require('NativeEventEmitter');
15+
const NativeModules = require('NativeModules');
16+
const Platform = require('Platform');
17+
const RCTNetInfo = NativeModules.NetInfo;
18+
19+
const NetInfoEventEmitter = new NativeEventEmitter(RCTNetInfo);
20+
21+
const DEVICE_CONNECTIVITY_EVENT = 'networkStatusDidChange';
22+
23+
type ChangeEventName = $Enum<{
24+
connectionChange: string,
25+
change: string,
26+
}>;
27+
28+
type ReachabilityStateIOS = $Enum<{
29+
cell: string,
30+
none: string,
31+
unknown: string,
32+
wifi: string,
33+
}>;
34+
35+
type ConnectivityStateAndroid = $Enum<{
36+
NONE: string,
37+
MOBILE: string,
38+
WIFI: string,
39+
MOBILE_MMS: string,
40+
MOBILE_SUPL: string,
41+
MOBILE_DUN: string,
42+
MOBILE_HIPRI: string,
43+
WIMAX: string,
44+
BLUETOOTH: string,
45+
DUMMY: string,
46+
ETHERNET: string,
47+
MOBILE_FOTA: string,
48+
MOBILE_IMS: string,
49+
MOBILE_CBS: string,
50+
WIFI_P2P: string,
51+
MOBILE_IA: string,
52+
MOBILE_EMERGENCY: string,
53+
PROXY: string,
54+
VPN: string,
55+
UNKNOWN: string,
56+
}>;
57+
58+
const _subscriptions = new Map();
59+
60+
let _isConnectedDeprecated;
61+
if (Platform.OS === 'ios') {
62+
_isConnectedDeprecated = function(
63+
reachability: ReachabilityStateIOS,
64+
): boolean {
65+
return reachability !== 'none' && reachability !== 'unknown';
66+
};
67+
} else if (Platform.OS === 'android') {
68+
_isConnectedDeprecated = function(
69+
connectionType: ConnectivityStateAndroid,
70+
): boolean {
71+
return connectionType !== 'NONE' && connectionType !== 'UNKNOWN';
72+
};
73+
}
74+
75+
function _isConnected(connection) {
76+
return connection.type !== 'none' && connection.type !== 'unknown';
77+
}
78+
79+
const _isConnectedSubscriptions = new Map();
80+
81+
/**
82+
* NetInfo exposes info about online/offline status.
83+
*
84+
* See https://facebook.github.io/react-native/docs/netinfo.html
85+
*/
86+
const NetInfo = {
87+
/**
88+
* Adds an event handler.
89+
*
90+
* See https://facebook.github.io/react-native/docs/netinfo.html#addeventlistener
91+
*/
92+
addEventListener(
93+
eventName: ChangeEventName,
94+
handler: Function,
95+
): {remove: () => void} {
96+
let listener;
97+
if (eventName === 'connectionChange') {
98+
listener = NetInfoEventEmitter.addListener(
99+
DEVICE_CONNECTIVITY_EVENT,
100+
appStateData => {
101+
handler({
102+
type: appStateData.connectionType,
103+
effectiveType: appStateData.effectiveConnectionType,
104+
});
105+
},
106+
);
107+
} else if (eventName === 'change') {
108+
console.warn(
109+
'NetInfo\'s "change" event is deprecated. Listen to the "connectionChange" event instead.',
110+
);
111+
112+
listener = NetInfoEventEmitter.addListener(
113+
DEVICE_CONNECTIVITY_EVENT,
114+
appStateData => {
115+
handler(appStateData.network_info);
116+
},
117+
);
118+
} else {
119+
console.warn('Trying to subscribe to unknown event: "' + eventName + '"');
120+
return {
121+
remove: () => {},
122+
};
123+
}
124+
125+
_subscriptions.set(handler, listener);
126+
return {
127+
remove: () => NetInfo.removeEventListener(eventName, handler),
128+
};
129+
},
130+
131+
/**
132+
* Removes the listener for network status changes.
133+
*
134+
* See https://facebook.github.io/react-native/docs/netinfo.html#removeeventlistener
135+
*/
136+
removeEventListener(eventName: ChangeEventName, handler: Function): void {
137+
const listener = _subscriptions.get(handler);
138+
if (!listener) {
139+
return;
140+
}
141+
listener.remove();
142+
_subscriptions.delete(handler);
143+
},
144+
145+
/**
146+
* This function is deprecated. Use `getConnectionInfo` instead.
147+
* Returns a promise that resolves with one of the deprecated connectivity
148+
* types:
149+
*
150+
* The following connectivity types are deprecated. They're used by the
151+
* deprecated APIs `fetch` and the `change` event.
152+
*
153+
* iOS connectivity types (deprecated):
154+
* - `none` - device is offline
155+
* - `wifi` - device is online and connected via wifi, or is the iOS simulator
156+
* - `cell` - device is connected via Edge, 3G, WiMax, or LTE
157+
* - `unknown` - error case and the network status is unknown
158+
*
159+
* Android connectivity types (deprecated).
160+
* - `NONE` - device is offline
161+
* - `BLUETOOTH` - The Bluetooth data connection.
162+
* - `DUMMY` - Dummy data connection.
163+
* - `ETHERNET` - The Ethernet data connection.
164+
* - `MOBILE` - The Mobile data connection.
165+
* - `MOBILE_DUN` - A DUN-specific Mobile data connection.
166+
* - `MOBILE_HIPRI` - A High Priority Mobile data connection.
167+
* - `MOBILE_MMS` - An MMS-specific Mobile data connection.
168+
* - `MOBILE_SUPL` - A SUPL-specific Mobile data connection.
169+
* - `VPN` - A virtual network using one or more native bearers. Requires
170+
* API Level 21
171+
* - `WIFI` - The WIFI data connection.
172+
* - `WIMAX` - The WiMAX data connection.
173+
* - `UNKNOWN` - Unknown data connection.
174+
*
175+
* The rest of the connectivity types are hidden by the Android API, but can
176+
* be used if necessary.
177+
*/
178+
fetch(): Promise<any> {
179+
console.warn(
180+
'NetInfo.fetch() is deprecated. Use NetInfo.getConnectionInfo() instead.',
181+
);
182+
return RCTNetInfo.getCurrentConnectivity().then(resp => resp.network_info);
183+
},
184+
185+
/**
186+
* See https://facebook.github.io/react-native/docs/netinfo.html#getconnectioninfo
187+
*/
188+
getConnectionInfo(): Promise<any> {
189+
return RCTNetInfo.getCurrentConnectivity().then(resp => {
190+
return {
191+
type: resp.connectionType,
192+
effectiveType: resp.effectiveConnectionType,
193+
};
194+
});
195+
},
196+
197+
/**
198+
* See https://facebook.github.io/react-native/docs/netinfo.html#getconnectioninfo
199+
*/
200+
setConnectionCheckUrl(url: string): void {
201+
RCTNetInfo.setConnectionCheckUrl(url);
202+
},
203+
204+
/**
205+
* An object with the same methods as above but the listener receives a
206+
* boolean which represents the internet connectivity.
207+
*
208+
* See https://facebook.github.io/react-native/docs/netinfo.html#isconnected
209+
*/
210+
isConnected: {
211+
addEventListener(
212+
eventName: ChangeEventName,
213+
handler: Function,
214+
): {remove: () => void} {
215+
const listener = connection => {
216+
if (eventName === 'change') {
217+
handler(_isConnectedDeprecated(connection));
218+
} else if (eventName === 'connectionChange') {
219+
handler(_isConnected(connection));
220+
}
221+
};
222+
_isConnectedSubscriptions.set(handler, listener);
223+
NetInfo.addEventListener(eventName, listener);
224+
return {
225+
remove: () =>
226+
NetInfo.isConnected.removeEventListener(eventName, handler),
227+
};
228+
},
229+
230+
removeEventListener(eventName: ChangeEventName, handler: Function): void {
231+
const listener = _isConnectedSubscriptions.get(handler);
232+
NetInfo.removeEventListener(
233+
eventName,
234+
/* $FlowFixMe(>=0.36.0 site=react_native_fb,react_native_oss) Flow error
235+
* detected during the deploy of Flow v0.36.0. To see the error, remove
236+
* this comment and run Flow */
237+
listener,
238+
);
239+
_isConnectedSubscriptions.delete(handler);
240+
},
241+
242+
fetch(): Promise<any> {
243+
return NetInfo.getConnectionInfo().then(_isConnected);
244+
},
245+
},
246+
247+
isConnectionExpensive(): Promise<boolean> {
248+
return Platform.OS === 'android'
249+
? RCTNetInfo.isConnectionMetered()
250+
: Promise.reject(new Error('Currently not supported on iOS'));
251+
},
252+
};
253+
254+
module.exports = NetInfo;

RNTester/js/NetInfoExample.js

+11-10
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ class ConnectionInfoSubscription extends React.Component<{}, $FlowFixMeState> {
2020
};
2121

2222
componentDidMount() {
23-
NetInfo.addEventListener('change', this._handleConnectionInfoChange);
23+
NetInfo.addEventListener('connectionChange', this._handleConnectionInfoChange);
2424
}
2525

2626
componentWillUnmount() {
27-
NetInfo.removeEventListener('change', this._handleConnectionInfoChange);
27+
NetInfo.removeEventListener('connectionChange', this._handleConnectionInfoChange);
2828
}
2929

3030
_handleConnectionInfoChange = connectionInfo => {
3131
const connectionInfoHistory = this.state.connectionInfoHistory.slice();
32-
connectionInfoHistory.push(connectionInfo);
32+
connectionInfoHistory.push(connectionInfo.type);
3333
this.setState({
3434
connectionInfoHistory,
3535
});
@@ -46,18 +46,18 @@ class ConnectionInfoSubscription extends React.Component<{}, $FlowFixMeState> {
4646

4747
class ConnectionInfoCurrent extends React.Component<{}, $FlowFixMeState> {
4848
state = {
49-
connectionInfo: null,
49+
connectionInfo: {type: 'not fetched', effectiveType: 'not fetched'},
5050
};
5151

5252
componentDidMount() {
53-
NetInfo.addEventListener('change', this._handleConnectionInfoChange);
54-
NetInfo.fetch().done(connectionInfo => {
53+
NetInfo.addEventListener('connectionChange', this._handleConnectionInfoChange);
54+
NetInfo.getConnectionInfo().then(connectionInfo => {
5555
this.setState({connectionInfo});
5656
});
5757
}
5858

5959
componentWillUnmount() {
60-
NetInfo.removeEventListener('change', this._handleConnectionInfoChange);
60+
NetInfo.removeEventListener('connectionChange', this._handleConnectionInfoChange);
6161
}
6262

6363
_handleConnectionInfoChange = connectionInfo => {
@@ -69,7 +69,8 @@ class ConnectionInfoCurrent extends React.Component<{}, $FlowFixMeState> {
6969
render() {
7070
return (
7171
<View>
72-
<Text>{this.state.connectionInfo}</Text>
72+
<Text>Type: {this.state.connectionInfo.type}</Text>
73+
<Text>Effective type: {this.state.connectionInfo.effectiveType}</Text>
7374
</View>
7475
);
7576
}
@@ -82,7 +83,7 @@ class IsConnected extends React.Component<{}, $FlowFixMeState> {
8283

8384
componentDidMount() {
8485
NetInfo.isConnected.addEventListener(
85-
'change',
86+
'connectionChange',
8687
this._handleConnectivityChange,
8788
);
8889
NetInfo.isConnected.fetch().done(isConnected => {
@@ -92,7 +93,7 @@ class IsConnected extends React.Component<{}, $FlowFixMeState> {
9293

9394
componentWillUnmount() {
9495
NetInfo.isConnected.removeEventListener(
95-
'change',
96+
'connectionChange',
9697
this._handleConnectivityChange,
9798
);
9899
}

0 commit comments

Comments
 (0)