Events
BioSDK uses a single Combine publisher to emit all SDK events. Subscribe to sdk.events to receive real-time updates about device lifecycle, biosignal data, connection state changes, and session activity.
import Combine
var cancellables = Set<AnyCancellable>()
sdk.events
.sink { event in
// Handle all event types
}
.store(in: &cancellables)
Event Types
BioEvent
The top-level event enum:
public enum BioEvent {
case lifecycle(BioLifecycleEvent)
case sample(deviceId: String, BioSample)
case deviceState(device: BioDevice, connection: BioConnectionState, stream: BioStreamState)
case session(BioSessionEvent)
case notification(BioNotificationEvent)
}
Lifecycle Events
Emitted when devices are discovered, connected, or disconnected.
public enum BioLifecycleEvent {
case discovered(BioDevice)
case connected(BioDevice)
case disconnected(BioDevice, errorMessage: String?, errorCode: Int?, errorDomain: String?)
}
Sample Events
Emitted for each biosignal data point received from a device. See the Streaming guide for details on signal types.
Device State Events
Emitted whenever a device's connection or streaming state changes. Each device has independent (BioConnectionState, BioStreamState) tracking.
Session Events
Emitted for session lifecycle changes on the AnyBio platform.
public enum BioSessionEvent {
case started(id: String, devices: [SessionDevice])
case resumed(id: String, devices: [SessionDevice])
case conflict(activeId: String, startedAt: Date?)
case ended(id: String, ok: Bool)
case endFailed(id: String, status: Int?)
case recoveryAvailable(OrphanedSessionInfo)
case forbidden
case serverError(status: Int)
case error(message: String)
}
Notification Events
Emitted for push notification activity (if notifications are configured).
public enum BioNotificationEvent {
case received(BioNotification)
case acknowledged(notificationId: String)
case dismissed(notificationId: String)
case connectionStateChanged(NotificationConnectionState)
}
Filtering Events
Use Combine operators to subscribe to specific event types:
// Only heart rate samples
sdk.events
.compactMap { event -> Double? in
guard case .sample(_, let sample) = event,
sample.isHeartRate,
let bpm = sample.scalarValue else { return nil }
return bpm
}
.sink { bpm in
print("HR: \(bpm) BPM")
}
.store(in: &cancellables)
// Only connection state changes
sdk.events
.compactMap { event -> (BioDevice, BioConnectionState)? in
guard case .deviceState(let device, let connection, _) = event else { return nil }
return (device, connection)
}
.sink { device, state in
print("\(device.name): \(state)")
}
.store(in: &cancellables)
Keep your event sink subscription alive for the lifetime of the SDK client. Store cancellables in a property that outlives any individual view — for example, on your app delegate or a long-lived coordinator.