SensorKit
Access granular ambient, motion, biometric, and interaction sensor streams for approved research and clinical studies using SRSensorReader. Targets Swift 6.3 / iOS 26+.
Entitlement Warning: SensorKit requires Apple entitlement approval (com.apple.developer.sensorkit.reader.allow). SensorKit cannot be tested on standard consumer apps or simulators without approved research provisioning.
Contents
Setup & Entitlements
- Obtain the research entitlement
com.apple.developer.sensorkit.reader.allow from Apple.
- Add sensor usage descriptions to Info.plist corresponding to each queried sensor (e.g.
NSSensorKitUsageDescription, NSSensorKitUsageDescriptionAmbientLightSensor).
- Request authorization explicitly before instantiating readers:
import SensorKit
func requestSensorAccess(for sensors: Set<SRSensor>) async {
let status = await SRSensorReader.requestAuthorization(for: sensors)
// Handle authorization response
}
Sensor Reader Lifecycle
Create an SRSensorReader per sensor type and assign an SRSensorReaderDelegate:
final class AmbientLightCollector: NSObject, SRSensorReaderDelegate {
private let reader = SRSensorReader(sensor: .ambientLightSensor)
override init() {
super.init()
reader.delegate = self
}
func start() {
guard reader.authorizationStatus == .authorized else { return }
reader.startRecording()
}
func stop() {
reader.stopRecording()
}
}
Fetching Sensor Data
Query historical recorded samples by date interval:
func fetchSamples(from start: SRAbsoluteTime, to end: SRAbsoluteTime) {
let request = SRFetchRequest()
request.from = start
request.to = end
reader.fetch(request)
}
// SRSensorReaderDelegate
func sensorReader(_ reader: SRSensorReader, fetching request: SRFetchRequest, didFetchResult result: SRFetchResult) -> Bool {
if let sample = result.sample as? SRAmbientLightSample {
// Process sensor sample
}
return true // Return true to continue fetching remaining results
}
func sensorReader(_ reader: SRSensorReader, didCompleteFetch request: SRFetchRequest) {
// Finished fetch
}
Available Sensor Categories
- Motion & Environment:
.ambientLightSensor, .accelerometer, .rotationRate, .elevation.
- User Interactions:
.keyboardMetrics, .deviceUsageReport, .messagesUsageReport, .phoneUsageReport.
- Physiological & Health:
.speechMetrics, .faceMetrics, .wristTemperature, .heartRate.
Data Deletion & User Privacy
Research participants can delete recorded data. Honor deletion requests via SRSensorReader:
func purgeData(before timestamp: SRAbsoluteTime) async throws {
let request = SRDeletionRequest()
request.endTime = timestamp
try await reader.delete(request)
}
Common Mistakes
- Shipping without Apple entitlement approval: SensorKit APIs fail immediately unless signed with an approved provisioning profile.
- Returning false in fetch delegate prematurely: Returning
false from didFetchResult halts subsequent sample delivery.
- Forgetting per-sensor usage descriptions: Each sensor type requires its dedicated Info.plist explanation key.
- Querying unbounded time intervals: Always constrain
SRFetchRequest to bounded start and end timestamps to avoid memory exhaustion.
- Assuming simulator support: SensorKit does not record or simulate hardware sensor streams on iOS Simulator.
Review Checklist
References
- Setup, sensor/delegate catalogs, and multi-sensor manager
- Keyboard, device, phone, visit, media, and wrist samples
- Speech, face, temperature, ECG/PPG, deletion, and testing
- SensorKit framework
- SRSensorReader
- SRSensor
- SRDevice
- SRFetchRequest
- Configuring your project for sensor reading
- com.apple.developer.sensorkit.reader.allow
1---2name: sensorkit3description: Access ambient, motion, biometric, and interaction research data using SensorKit. Use when configuring sensor readers, handling authorization and study onboarding, fetching sample streams, managing user data deletion, or building research and clinical studies.4---56# SensorKit78Access granular ambient, motion, biometric, and interaction sensor streams for approved research and clinical studies using `SRSensorReader`. Targets Swift 6.3 / iOS 26+.910> **Entitlement Warning:** SensorKit requires Apple entitlement approval (`com.apple.developer.sensorkit.reader.allow`). SensorKit cannot be tested on standard consumer apps or simulators without approved research provisioning.1112## Contents1314- [Setup & Entitlements](#setup--entitlements)15- [Sensor Reader Lifecycle](#sensor-reader-lifecycle)16- [Fetching Sensor Data](#fetching-sensor-data)17- [Available Sensor Categories](#available-sensor-categories)18- [Data Deletion & User Privacy](#data-deletion--user-privacy)19- [Common Mistakes](#common-mistakes)20- [Review Checklist](#review-checklist)21- [References](#references)2223## Setup & Entitlements24251. Obtain the research entitlement `com.apple.developer.sensorkit.reader.allow` from Apple.262. Add sensor usage descriptions to Info.plist corresponding to each queried sensor (e.g. `NSSensorKitUsageDescription`, `NSSensorKitUsageDescriptionAmbientLightSensor`).273. Request authorization explicitly before instantiating readers:2829```swift30import SensorKit3132func requestSensorAccess(for sensors: Set<SRSensor>) async {33 let status = await SRSensorReader.requestAuthorization(for: sensors)34 // Handle authorization response35}36```3738## Sensor Reader Lifecycle3940Create an `SRSensorReader` per sensor type and assign an `SRSensorReaderDelegate`:4142```swift43final class AmbientLightCollector: NSObject, SRSensorReaderDelegate {44 private let reader = SRSensorReader(sensor: .ambientLightSensor)4546 override init() {47 super.init()48 reader.delegate = self49 }5051 func start() {52 guard reader.authorizationStatus == .authorized else { return }53 reader.startRecording()54 }5556 func stop() {57 reader.stopRecording()58 }59}60```6162## Fetching Sensor Data6364Query historical recorded samples by date interval:6566```swift67func fetchSamples(from start: SRAbsoluteTime, to end: SRAbsoluteTime) {68 let request = SRFetchRequest()69 request.from = start70 request.to = end7172 reader.fetch(request)73}7475// SRSensorReaderDelegate76func sensorReader(_ reader: SRSensorReader, fetching request: SRFetchRequest, didFetchResult result: SRFetchResult) -> Bool {77 if let sample = result.sample as? SRAmbientLightSample {78 // Process sensor sample79 }80 return true // Return true to continue fetching remaining results81}8283func sensorReader(_ reader: SRSensorReader, didCompleteFetch request: SRFetchRequest) {84 // Finished fetch85}86```8788## Available Sensor Categories8990- **Motion & Environment**: `.ambientLightSensor`, `.accelerometer`, `.rotationRate`, `.elevation`.91- **User Interactions**: `.keyboardMetrics`, `.deviceUsageReport`, `.messagesUsageReport`, `.phoneUsageReport`.92- **Physiological & Health**: `.speechMetrics`, `.faceMetrics`, `.wristTemperature`, `.heartRate`.9394## Data Deletion & User Privacy9596Research participants can delete recorded data. Honor deletion requests via `SRSensorReader`:9798```swift99func purgeData(before timestamp: SRAbsoluteTime) async throws {100 let request = SRDeletionRequest()101 request.endTime = timestamp102 try await reader.delete(request)103}104```105106## Common Mistakes107108- **Shipping without Apple entitlement approval**: SensorKit APIs fail immediately unless signed with an approved provisioning profile.109- **Returning false in fetch delegate prematurely**: Returning `false` from `didFetchResult` halts subsequent sample delivery.110- **Forgetting per-sensor usage descriptions**: Each sensor type requires its dedicated Info.plist explanation key.111- **Querying unbounded time intervals**: Always constrain `SRFetchRequest` to bounded start and end timestamps to avoid memory exhaustion.112- **Assuming simulator support**: SensorKit does not record or simulate hardware sensor streams on iOS Simulator.113114## Review Checklist115116- [ ] `com.apple.developer.sensorkit.reader.allow` entitlement confirmed active117- [ ] Required sensor usage descriptions declared in Info.plist118- [ ] `requestAuthorization(for:)` called before starting reader recording119- [ ] `didFetchResult` returns `true` while iterating batch samples120- [ ] Deletion requests supported for participant privacy compliance121122## References123124- [Setup, sensor/delegate catalogs, and multi-sensor manager](references/setup-catalog-and-manager.md)125- [Keyboard, device, phone, visit, media, and wrist samples](references/usage-and-environment-samples.md)126- [Speech, face, temperature, ECG/PPG, deletion, and testing](references/speech-face-and-health-samples.md)127- [SensorKit framework](https://sosumi.ai/documentation/sensorkit)128- [SRSensorReader](https://sosumi.ai/documentation/sensorkit/srsensorreader)129- [SRSensor](https://sosumi.ai/documentation/sensorkit/srsensor)130- [SRDevice](https://sosumi.ai/documentation/sensorkit/srdevice)131- [SRFetchRequest](https://sosumi.ai/documentation/sensorkit/srfetchrequest)132- [Configuring your project for sensor reading](https://sosumi.ai/documentation/sensorkit/configuring-your-project-for-sensor-reading)133- [com.apple.developer.sensorkit.reader.allow](https://sosumi.ai/documentation/bundleresources/entitlements/com.apple.developer.sensorkit.reader.allow)