neurofit_vitals is a thin wrapper: every call is forwarded over a MethodChannel to the native
NeurofitVitals (Swift) or com.neurofit.vitals (Kotlin) SDK, and events arrive over an EventChannel. There
is no reading logic in Dart. Event names and payload keys are the same as the React Native and Capacitor
wrappers; the Dart types mirror them.
1
Add the package
The package is delivered with your license. Add it as a path dependency (or publish it to your private pub
server).Then
pubspec.yaml
flutter pub get. The plugin’s podspec links NeurofitVitals.xcframework (binary license) or the
Swift package sources (source license); the Android module depends on com.neurofit:vitals-sdk:1.0.0, so
make that artifact resolvable from mavenLocal() or your artifact repository and set minSdk to 28 or
higher in android/app/build.gradle. iOS needs a deployment target of 15.0 or higher.2
Platform setup
iOS: add
NSCameraUsageDescription to ios/Runner/Info.plist (see the iOS quickstart).
Adding NSMotionUsageDescription as well is recommended while motionBreathing is on.Android: the plugin’s manifest declares android.permission.CAMERA, so nothing to add. See the
Android quickstart for the optional uses-feature entries.3
Activate and check the device
PlatformException. Its code is one of the VitalsErrorCode string
constants, which are the native error cases (VitalsErrorCode.licenseInvalid, licenseNotValidForApp,
licenseUpdatesExpired, cameraDenied, …) plus the wrapper-level sessionNotFound; message is the
native description. See License keys.4
Run a reading
createSession returns the session handle as a String; wrap it in VitalsSession(sessionId) for an
object-style API over the same calls. Listen to session.events before calling start; the wrapper does
not buffer events. session.events is NeurofitVitals.events (every session) filtered to this session;
every event carries its sessionId.start fails with a PlatformException whose code is the native error (notActivated, alreadyRunning,
cameraDenied, cameraRestricted, unsupportedDevice, on iOS also cameraUnavailable); on Android a camera
that cannot be opened arrives afterwards as a FailedEvent with code cameraUnavailable. cancelReading
applies while measuring only.5
Use the result
VitalsResult mirrors the camelCase result map listed on the
React Native quickstart field for field (capturedAt
as a DateTime, quality as SignalQuality); diagnostics is the snake_case map passed through
unchanged. Field meanings are on the Metrics page.Camera preview
The camera preview is optional on every platform: a fingertip covers the lens during a reading. The V1 wrapper does not render it; show the guidance text and the live values in your own widgets. A preview widget is planned; see Roadmap.Foreground, orientation and screen
A reading needs the app in the foreground for the whole minute: backgrounding (iOS) or the host activity’sON_STOP (Android) during positioning or measuring ends the session with a FailedEvent whose error.code is
interrupted. Lock the reading screen’s orientation while a session runs (SystemChrome.setPreferredOrientations)
and keep the screen awake (for example with the wakelock_plus package).
On Android the plugin works with the default FlutterActivity (it falls back to ActivityCompat.requestPermissions
for the camera prompt). Extending FlutterFragmentActivity (a ComponentActivity) is optional and opts into the
SDK-owned ActivityResultRegistry request; either way lock the orientation of the screen that asks.
Dart API
Next steps
- Reading lifecycle: what each event means and when it fires.
- Metrics: field definitions, units and validated accuracy.
- Troubleshooting: permission, torch and frame-rate issues.