react-native/Libraries/Network/NetInfo.js

241 lines
6.2 KiB
JavaScript

/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule NetInfo
* @flow
*/
'use strict';
var Map = require('Map');
var NativeModules = require('NativeModules');
var Platform = require('Platform');
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var RCTNetInfo = NativeModules.NetInfo;
var DEVICE_REACHABILITY_EVENT = 'networkDidChange';
type ChangeEventName = $Enum<{
change: string;
}>;
type ReachabilityStateIOS = $Enum<{
cell: string;
none: string;
unknown: string;
wifi: string;
}>;
type ConnectivityStateAndroid = $Enum<{
NONE: string;
MOBILE: string;
WIFI: string;
MOBILE_MMS: string;
MOBILE_SUPL: string;
MOBILE_DUN: string;
MOBILE_HIPRI: string;
WIMAX: string;
BLUETOOTH: string;
DUMMY: string;
ETHERNET: string;
MOBILE_FOTA: string;
MOBILE_IMS: string;
MOBILE_CBS: string;
WIFI_P2P: string;
MOBILE_IA: string;
MOBILE_EMERGENCY: string;
PROXY: string;
VPN: string;
UNKNOWN: string;
}>;
/**
* NetInfo exposes info about online/offline status
*
* ```
* NetInfo.fetch().done((reach) => {
* console.log('Initial: ' + reach);
* });
* function handleFirstConnectivityChange(reach) {
* console.log('First change: ' + reach);
* NetInfo.removeEventListener(
* 'change',
* handleFirstConnectivityChange
* );
* }
* NetInfo.addEventListener(
* 'change',
* handleFirstConnectivityChange
* );
* ```
*
* ### IOS
*
* Asynchronously determine if the device is online and on a cellular network.
*
* - `none` - device is offline
* - `wifi` - device is online and connected via wifi, or is the iOS simulator
* - `cell` - device is connected via Edge, 3G, WiMax, or LTE
* - `unknown` - error case and the network status is unknown
*
* ### Android
*
* Asynchronously determine if the device is connected and details about that connection.
*
* Android Connectivity Types
* - `NONE` - device is offline
* - `BLUETOOTH` - The Bluetooth data connection.
* - `DUMMY` - Dummy data connection.
* - `ETHERNET` - The Ethernet data connection.
* - `MOBILE` - The Mobile data connection.
* - `MOBILE_DUN` - A DUN-specific Mobile data connection.
* - `MOBILE_HIPRI` - A High Priority Mobile data connection.
* - `MOBILE_MMS` - An MMS-specific Mobile data connection.
* - `MOBILE_SUPL` - A SUPL-specific Mobile data connection.
* - `VPN` - A virtual network using one or more native bearers. Requires API Level 21
* - `WIFI` - The WIFI data connection.
* - `WIMAX` - The WiMAX data connection.
* - `UNKNOWN` - Unknown data connection.
* The rest ConnectivityStates are hidden by the Android API, but can be used if necessary.
*
* ### isConnectionMetered
*
* Available on Android. Detect if the current active connection is metered or not. A network is
* classified as metered when the user is sensitive to heavy data usage on that connection due to
* monetary costs, data limitations or battery/performance issues.
*
* NetInfo.isConnectionMetered((isConnectionMetered) => {
* console.log('Connection is ' + (isConnectionMetered ? 'Metered' : 'Not Metered'));
* });
* ```
*
* ### isConnected
*
* Available on all platforms. Asynchronously fetch a boolean to determine
* internet connectivity.
*
* ```
* NetInfo.isConnected.fetch().done((isConnected) => {
* console.log('First, is ' + (isConnected ? 'online' : 'offline'));
* });
* function handleFirstConnectivityChange(isConnected) {
* console.log('Then, is ' + (isConnected ? 'online' : 'offline'));
* NetInfo.isConnected.removeEventListener(
* 'change',
* handleFirstConnectivityChange
* );
* }
* NetInfo.isConnected.addEventListener(
* 'change',
* handleFirstConnectivityChange
* );
* ```
*/
var _subscriptions = new Map();
if (Platform.OS === 'ios') {
var _isConnected = function(
reachability: ReachabilityStateIOS
): bool {
return reachability !== 'none' &&
reachability !== 'unknown';
};
} else if (Platform.OS === 'android') {
var _isConnected = function(
connectionType: ConnectivityStateAndroid
): bool {
return connectionType !== 'NONE' && connectionType !== 'UNKNOWN';
};
}
var _isConnectedSubscriptions = new Map();
var NetInfo = {
addEventListener: function (
eventName: ChangeEventName,
handler: Function
): void {
var listener = RCTDeviceEventEmitter.addListener(
DEVICE_REACHABILITY_EVENT,
(appStateData) => {
handler(appStateData.network_info);
}
);
_subscriptions.set(handler, listener);
},
removeEventListener: function(
eventName: ChangeEventName,
handler: Function
): void {
var listener = _subscriptions.get(handler);
if (!listener) {
return;
}
listener.remove();
_subscriptions.delete(handler);
},
fetch: function(): Promise {
return new Promise((resolve, reject) => {
RCTNetInfo.getCurrentReachability(
function(resp) {
resolve(resp.network_info);
},
reject
);
});
},
isConnected: {
addEventListener: function (
eventName: ChangeEventName,
handler: Function
): void {
var listener = (connection) => {
handler(_isConnected(connection));
};
_isConnectedSubscriptions.set(handler, listener);
NetInfo.addEventListener(
eventName,
listener
);
},
removeEventListener: function(
eventName: ChangeEventName,
handler: Function
): void {
var listener = _isConnectedSubscriptions.get(handler);
NetInfo.removeEventListener(
eventName,
listener
);
_isConnectedSubscriptions.delete(handler);
},
fetch: function(): Promise {
return NetInfo.fetch().then(
(connection) => _isConnected(connection)
);
},
},
isConnectionMetered: ({}: {} | (callback:Function) => void),
};
if (Platform.OS === 'android') {
NetInfo.isConnectionMetered = function(callback): void {
RCTNetInfo.isConnectionMetered((_isMetered) => {
callback(_isMetered);
});
};
}
module.exports = NetInfo;