On-device behavioral signal capture for iOS applications
Overview
The Synheart Behavior Swift/iOS SDK captures digital interaction events on-device — the eight BehaviorEventType cases are scroll, tap, swipe, appSwitch, notification, call, typing, and clipboard — and streams them to your app. Behavior is content-free — no text, no screen content, no PII.The SDK is an input layer: it produces events and raw per-session counts. It does not compute focus, distraction or typing aggregates; that is done downstream by Synheart Core when behavior is fed into it.
Installation
Swift Package Manager
Add to your Package.swift or in Xcode (File → Add Packages…):
import SynheartBehaviorlet config = BehaviorConfig( enableInputSignals: true, enableAttentionSignals: true)let behavior = SynheartBehavior(config: config)try behavior.initialize()// Real-time events: a callback...behavior.setEventHandler { event in print("Event: \(event.eventType) at \(event.timestamp): \(event.metrics)")}// ...or an AsyncStreamTask { for await event in behavior.events { print(event.eventType) }}// Start a sessionlet session = try behavior.startSession()// ... user interacts with app ...let summary = try session.end() // or behavior.endSession(sessionId: session.sessionId)print("Duration: \(summary.duration) ms")print("Total events: \(summary.activitySummary.totalEvents)")print("App switches: \(summary.activitySummary.appSwitchCount)")
summary.behavioralMetricsStruct, summary.typingSessionSummary and
summary.motionState are always nil: the SDK reports raw counts and leaves
scoring to Synheart Core.
Clipboard events
The SDK does not observe the system clipboard. Report copy, paste and cut
yourself (for example from a UITextField subclass that overrides copy(_:),
paste(_:) and cut(_:)):
Notifications: forward your UNUserNotificationCenterDelegate callbacks
to behavior.notificationDelivered(id:) and behavior.notificationOpened(id:).
Or set BehaviorConfig(installNotificationDelegate: true) and the SDK installs
itself as the delegate, forwarding every callback to the delegate it replaced.
Calls: collected through CallKit when enableAttentionSignals is on.
Permissions:checkNotificationPermission(), requestNotificationPermission(),
checkCallPermission() and requestCallPermission() are async and return Bool.
Raw motion
enableMotionLite is accepted but collects nothing on iOS yet. For raw
accelerometer data, set emitRawMotionSamples: true and register a handler;
samples arrive at 50 Hz in 1-second batches:
let behavior = SynheartBehavior(config: BehaviorConfig(emitRawMotionSamples: true))behavior.setRawMotionSampleHandler { batch in // [[String: Any]], one dictionary per sample}
Event behavior
Taps and long press: Not counted when a text field or text view is first responder (keyboard open), so typing is not double-counted as taps.
Typing events: carry timing metrics (speed, cadence, gaps, burstiness) and backspace_count. No characters are ever captured.
Errors
Calls throw BehaviorError: notInitialized, invalidConfiguration or
sessionNotFound.
API summary
Method / property
Description
initialize()
Initialize the SDK
startSession(sessionId:)
Start a session; returns a BehaviorSession
endSession(sessionId:)
End session and return BehaviorSessionSummary
setEventHandler(_:) / setBatchEventHandler(_:)
Callbacks for single events or batches
events
AsyncStream<BehaviorEvent>
sendEvent(_:)
Send an event yourself (for example .clipboard(...))