Activity Recognition
Run ContextSDK's on-device activity recognition models on demand and read back the probability that the user is walking, in transit, sitting, and more.
ContextSDK can predict the user's current physical activity (walking, sitting, in transit, etc.) from the device's motion sensors. The result is a set of probabilities you can read directly, with no logged conversion needed.
Getting access
The activity recognition API is not included in the default ContextSDK build. If you'd like to use it, get in touch with us so we can enable it for your app and ship you a build that includes the fetchCurrentActivity API. Without it the symbols below won't be visible from your app.
Fetching the full result
ContextManager.fetchCurrentActivity collects a short window of motion sensor data, runs the bundled activity models, and returns the probability for every activity ContextSDK can detect. The callback fires once on the main thread, typically a few seconds after the call.
Pass a flowName that identifies the call site (e.g. "home_screen_tap", "notification_received"). Use a distinct value for each place in your app where you invoke this API.
ContextManager.fetchCurrentActivity(flowName: "home_screen_tap") { status, result in
guard status == .ok else {
// The call didn't run; see the status reference below.
return
}
if let walking = result.walking {
print("walking: \(walking.probability ?? 0)")
print(" running: \(walking.running ?? 0)")
print(" stairs: \(walking.stairs ?? 0)")
}
if let transit = result.transit {
print("transit: \(transit.probability ?? 0)")
print(" train: \(transit.train ?? 0)")
print(" tram: \(transit.tram ?? 0)")
print(" subway: \(transit.subway ?? 0)")
}
print("bike: \(result.bike ?? 0)")
print("car: \(result.car ?? 0)")
}Group activities such as walking, transit, sittingOrStanding, table, and bed are exposed as nested structs that contain both the group probability and its sub-activities. Leaf activities (bike, car, airplane, pocket) are exposed as Float? directly on the result. A nil field means the model didn't produce a score for that activity in this call.
Scoring a subset of activities
If you only care about a few activities, pass them explicitly. The SDK will only load and run the matching models, which keeps CPU and memory usage lower than the full call.
The scores dictionary is keyed by the Activity values you requested. Activities that didn't produce a score are omitted from the dictionary; an empty dictionary means the call didn't run successfully, so check status.
Status reference
Both overloads pass an ActivityRecognitionStatus alongside the result so you can tell a successful prediction with low scores apart from a call that didn't run.
.ok
The models ran. Individual probabilities may still be nil if a particular activity couldn't be scored, but the result is meaningful.
.timeout
The SDK couldn't collect enough motion data in time. Retry later (e.g. when the user is more likely to be holding the device steady).
.sensorUnavailable
The device has no usable accelerometer or gyroscope (e.g. an iOS app running on a Mac without device hosting). Subsequent calls on the same device will return the same status.
Threading and timing
The callback is always invoked on the main thread.
The call is asynchronous; expect the callback a few seconds after invocation while the SDK collects sensor data.
You can call this API from a background context (e.g. a notification service extension). The accelerometer is started and stopped automatically for the duration of the call.
Last updated
Was this helpful?