Skip to main content
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).
pubspec.yaml
Then 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

Every method fails with Flutter’s 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’s ON_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