Skip to main content

Filtering Lists

Activities, subjects, sessions and subject groups are all listed the same way: list(...) takes the filters you want and returns a sequence you iterate directly.

Every sequence also carries total, the number of matching items, and all(), which collects the rest into an array.

Activities​

let activities = client.activities.list(search: "squat", onlyCompleted: true)

for try await activity in activities {
print(activity.name ?? activity.id, activity.status)
}

Calibration and neutral-pose activities are left out by default. Pass excludeCalibration: false to include them.

FilterSelects
subjectActivities recorded for one subject
calibrationSessionActivities recorded under one calibration session
activityTypeActivities of one type — see Activity Types
excludeCalibrationWhether to leave out calibration and neutral-pose activities (default true)
createdAfter / createdBeforeAn inclusive date range
searchFree-text match against the activity name
tagsActivities carrying every tag in the list
createdByActivities belonging to one or more account ids
onlyCompletedActivities whose recording finished
excludeAnalysisErrorLeaves out activities whose analysis failed

Subjects​

for try await subject in client.subjects.list(activityComplete: true) {
print(subject.id, subject.name)
}
FilterSelects
searchFree-text match against the subject name
createdAfter / createdBeforeAn inclusive date range
groupsSubjects belonging to one of these subject groups
tagsSubjects carrying every tag in the list
createdBySubjects belonging to one or more account ids
activityTypeSubjects with an activity of this type — see Activity Types
activityCompleteSubjects with at least one completed activity
sessionSubjects recorded in one session

Sessions​

let sessions = try await client.sessions.list(subject: subject).all()

Narrowing by subject is the only filter a session list takes. It lists sessions on your own account.

Subject Groups​

for try await group in client.groups.list(search: "study") {
print(group.name, group.subjectCount)
}

Search is the only filter a group list takes.

Activity Types​

The types available are the account's own: the ones everybody has, plus any the account or its organisation added. Read them, then filter by one.

let types = try await client.activityTypes()
let squats = types.first { $0.displayName == "Squat Exercise" }!

for try await activity in client.activities.list(activityType: squats) {
print(activity.name ?? activity.id)
}

A type carries id, name, slug and displayName, and — when read from this list — description and isCustom.

Match on slug rather than on a name. It is derived from the name once and then stays put, so renaming a type leaves it alone, while name and displayName both follow the rename:

let squats = try await client.activityTypes().first { $0.slug == "squat_exercise" }!

The one already on an activity works as a filter too, so you can narrow to whatever you just saw:

client.activities.list(activityType: activity.activityType!)

Sorting​

Pass orderBy to choose the field, prefixed with - for descending. Swift takes a typed enum instead of a string.

client.activities.list(orderBy: .createdAtDescending)
client.subjects.list(orderBy: .name)
ListSort by
ActivitiescreatedAt, status, createdBy, activityType
Subjectsname, createdAt, updatedAt
Sessionsname, createdAt
Subject groupsname

A field the list can't sort by is refused straight away, with an error naming the ones it accepts.

Counting Matches​

total is the number of items matching the filter, not the number you have read. It is available before you start iterating, and reading it does not consume any items.

let activities = client.activities.list(tags: ["baseline"])
print("\(try await activities.total) match")

Collecting Everything​

all() returns every remaining match as an array, continuing from wherever iteration stopped. Use limit to cap how many items a sequence yields in total.

let recent = try await client.activities.list(orderBy: .createdAtDescending, limit: 20).all()

Stopping Early​

In TypeScript, call close() on a sequence you stop reading early. Reading one to the end does this for you. Swift and Python need no equivalent.

for try await activity in client.activities.list() {
if activity.status == "done" { break }
}