react-native-altimeter
v0.1.1
Published
A typed React Native TurboModule for atmospheric pressure, relative altitude, and absolute altitude.
Maintainers
Readme
react-native-altimeter
A typed React Native TurboModule for atmospheric pressure, relative altitude, and absolute altitude on iOS and Android.
Installation
npm install react-native-altimeterReact Native 0.80 or newer with the New Architecture enabled is required.
On iOS, add a meaningful NSMotionUsageDescription to your app's
Info.plist. Apple documents that an app can terminate when it starts
CMAltimeter without this key.
<key>NSMotionUsageDescription</key>
<string>Altitude is used to measure elevation changes during an activity.</string>Then install CocoaPods dependencies in the usual way for your project. Android does not require a runtime permission for the pressure sensor.
Usage
import { useEffect } from 'react';
import {
onUpdate,
setInterval as setAltimeterInterval,
start,
stop,
} from 'react-native-altimeter';
export function AltitudeTracker() {
useEffect(() => {
setAltimeterInterval(1000);
const subscription = onUpdate(
(data) => {
console.log('pressure', data.pressureKPa);
console.log('relative altitude', data.relativeAltitude);
console.log('absolute altitude', data.absoluteAltitude);
},
(error) => console.warn(error.code, error.message)
);
start({ mode: 'both' }).catch(console.warn);
return () => {
subscription.remove();
stop();
};
}, []);
return null;
}Subscribe before calling start() so that the first relative sample, whose
altitude is 0, is not missed.
API
start(options?)
start(options?: {
mode?: 'relative' | 'absolute' | 'both';
}): Promise<void>;Starts native updates. The default mode is both. The promise resolves after
the native session is accepted (or scheduled for Android host resume); it does
not wait for the first sample.
Calling start again safely restarts the session, so relative altitude uses a
new zero point.
relativeemits pressure and altitude change from the first sample.absoluteuses the native absolute-altitude estimate where available and a pressure-based estimate otherwise.bothcollects both streams and is the default.
The promise rejects if the requested data is unavailable, the iOS usage
description is missing, or motion access is already denied or restricted. On
the first iOS request, start() triggers the system permission flow and may
resolve before the user responds; a subsequent denial is delivered to the
errorListener and stops the session.
stop()
Stops all native updates. Calling it more than once is safe. Removing an event subscription does not stop the native sensor; call both during cleanup.
setInterval(intervalMs)
Sets the minimum interval between events from the same native data stream. The
default is 1000 ms. 0 disables throttling. The value must be finite and at
least zero.
Invalid values throw a synchronous RangeError before native code is called.
This is not an exact hardware sampling rate. CMAltimeter controls its own
update cadence, and Android treats its sensor sampling period as a hint. In
both mode, iOS relative and absolute updates are independent streams and may
arrive close together.
onUpdate(listener, errorListener?)
Registers update and optional runtime-error listeners and returns an object
with an idempotent remove() method. A missing or invalid listener throws a
synchronous TypeError.
type AltimeterUpdate = {
timestamp: number;
pressureKPa: number | null;
relativeAltitude: number | null;
absoluteAltitude: number | null;
absoluteAltitudeSource: 'native' | 'barometric' | null;
absoluteAltitudeAccuracy: number | null;
absoluteAltitudePrecision: number | null;
};All altitude, accuracy, and precision values are metres. timestamp is Unix
epoch time in milliseconds. Pressure is always kilopascals; Android's native
hPa value is converted before it reaches JavaScript.
Pressure/relative and native absolute values come from separate callbacks on
iOS. In absolute or both mode, either callback can arrive first, so an
initial update can contain only that stream's values. Every payload contains
the latest values admitted by each stream's interval throttle. Accuracy and
precision describe Apple's native absolute-altitude estimate and are null
for pressure-based estimates.
Field availability by mode:
| Mode | Pressure | Relative altitude | Absolute altitude |
| ---------- | ---------------------------------------------------------- | ---------------------------------------------- | ------------------------------------- |
| relative | Value after the relative stream's first sample | Value after the relative stream's first sample | null |
| absolute | Value after a pressure sample, when that stream is present | null | Value after its stream's first sample |
| both | Value after the relative stream's first sample | Value after the relative stream's first sample | Value after its stream's first sample |
Runtime errors stop the active session. Native start rejections and the optional error listener use these codes (React Native exposes a rejected native promise's code on the resulting error object):
| Code | Meaning |
| --------------------------------------- | ------------------------------------------------------ |
| E_MISSING_USAGE_DESCRIPTION | The iOS host app omitted NSMotionUsageDescription |
| E_ALTIMETER_UNAVAILABLE | The sensor or requested altitude source is unavailable |
| E_PERMISSION_DENIED | Motion access was denied |
| E_PERMISSION_RESTRICTED | Motion access is restricted by the system |
| E_ALTIMETER_UPDATE | A native update failed or contained invalid data |
| E_INVALID_MODE / E_INVALID_INTERVAL | Native defensive validation failed |
The JavaScript wrapper validates these arguments first: an invalid mode rejects
start() with a TypeError, while an invalid interval throws a synchronous
RangeError. Those validation errors do not carry native error codes.
Platform behavior
| Platform | Relative altitude | Absolute altitude |
| -------- | ------------------------------------------------- | -------------------------------------------------------- |
| iOS | Native CMAltimeter, relative to the first event | Native on supported devices; pressure fallback otherwise |
| Android | Pressure sensor, relative to the first event | Estimate from pressure and standard sea-level pressure |
Apple's native absolute altitude is available on iPhone 12 and newer.
The pressure fallback uses a standard sea-level pressure of 101.325 kPa and
is sensitive to weather and local pressure, so it is an estimate rather than a
survey-grade elevation. Android devices without a barometer are unsupported.
Android sensor delivery pauses while the host Activity is paused and resumes
with the same relative-altitude baseline when the Activity returns.
See Apple's CMAltimeter documentation
and Android's SensorManager.getAltitude
for the underlying platform behavior.
Contributing
License
MIT
