For the complete documentation index, see llms.txt. This page is also available as Markdown.

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.

Status
Meaning

.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?