Activities
The Activities module provides calendar-based access to a member's activity history. Query by month and year to retrieve aggregate statistics and individual activity records -- gym visits, step tracking, self-reports, and at-home workouts.
UI Reference
Build a monthly calendar that color-codes each day by activity type and status. Use get(month, year) to populate the grid and summary statistics.
Key data mappings:
| UI Element | AFCore Source |
|---|---|
| Month header & progress bar | monthlySummary.acceptedActivities / monthlySummary.acceptedVisitGoalDays |
| Day activity dots | activities grouped by date, colored by ActivityType |
| Summary counters | monthlySummary.acceptedActivities, .pendingActivities, .rejectedActivities |
| Legend colors | GYM_VISIT_ACTIVITY (green), SMART_WALKING_ACTIVITY (blue), HOME_ACTIVITY (orange) |
Data Model
AFActivitiesSummary
Returned by get(), this contains both the monthly aggregate and the list of individual activities.
| Field | Type | Description |
|---|---|---|
monthlySummary | MonthlySummary? | Aggregate statistics for the requested month. |
activities | List<Activity> | Individual activity records for the month. |
MonthlySummary
| Field | Type | Description |
|---|---|---|
month | Int | Calendar month (1--12). |
year | Int | Calendar year. |
acceptedVisitGoalDays | Int | Number of days the visit goal was met. |
acceptedVisitDays | Int | Number of days with at least one accepted visit. |
acceptedActivities | Int | Total accepted activities in the month. |
pendingActivities | Int | Activities awaiting verification. |
rejectedActivities | Int | Activities that were denied. |
Activity
| Field | Type | Description |
|---|---|---|
type | ActivityType? | Category of the activity. |
name | String? | Display name (e.g., facility name or "SmartWalking"). |
iconRes | String? | Optional icon resource identifier. |
statusType | ActivityStatus | Current verification status. |
date | String? | Date of the activity (ISO-8601). |
metaData | ActivityMetaData? | Additional details specific to the activity type. |
message | String? | Server message (e.g., rejection reason). |
ActivityType
| Value | Key | Description |
|---|---|---|
GYM_VISIT_ACTIVITY | "gym" | Facility visit detected by geofencing. |
SMART_WALKING_ACTIVITY | "walking" | Step-based activity from SmartWalking. |
SELF_REPORTED_ACTIVITY | "mobileSelfReport" | Manually submitted visit report. |
HOME_ACTIVITY | "fitAtHome" | At-home workout verified by selfie. |
ActivityStatus
| Value | Description |
|---|---|
APPROVED / ACCEPTED / COMPLETED | Activity was verified and counts toward goals. Treat these as equivalent. |
PENDING | Activity is awaiting verification or still in progress. |
DENIED / REJECTED | Activity did not pass validation. Check Activity.message for the reason. |
PARTIAL | Activity was recorded but did not meet the required threshold (e.g., insufficient steps). |
IGNORE | Recorded for tracking purposes only; does not count toward goals. |
DEFAULT | Fallback when the server returns an unmapped status. |
ActivityMetaData
| Field | Type | Description |
|---|---|---|
facilityId | Int? | Facility identifier. |
facilityName | String? | Display name of the facility. |
address | String? | Street address. |
city | String? | City. |
state | String? | Two-letter state code. |
description | String? | Description (used for custom activity types). |
timeSpent | Int? | Duration in minutes. |
steps | Int? | Step count (SmartWalking activities). |
distance | Double? | Distance traveled. |
distanceUnit | String? | Unit of distance ("Miles" or "Kilometers"). |
calories | Double? | Calories burned (SmartWalking activities). |
activeMinutes | Int? | Active minutes (SmartWalking activities). |
lastSync | String? | Timestamp of the last sync for this activity. |
Get Activities
Retrieve the monthly summary and activity list for a given month and year.
- Android (Kotlin)
- iOS (Swift)
lifecycleScope.launch {
try {
val result = AFCore.activities().get(month = 2, year = 2026)
// Display monthly progress
result.monthlySummary?.let { summary ->
progressBar.max = summary.acceptedVisitGoalDays
progressBar.progress = summary.acceptedVisitDays
summaryLabel.text = "${summary.acceptedActivities} accepted, " +
"${summary.pendingActivities} pending, " +
"${summary.rejectedActivities} rejected"
}
// Group activities by date for a calendar view
val activitiesByDate = result.activities
.groupBy { it.date?.substringBefore("T") }
calendarAdapter.submitGrouped(activitiesByDate)
} catch (e: Exception) {
showError("Could not load activities: ${e.message}")
}
}
do {
let result = try await AFCore.shared.activities().get(month: 2, year: 2026)
// Display monthly progress
if let summary = result.monthlySummary {
progressView.total = summary.acceptedVisitGoalDays
progressView.current = summary.acceptedVisitDays
}
// Group activities by date for a calendar view
let grouped = Dictionary(grouping: result.activities) { activity in
activity.date?.prefix(10) ?? "Unknown"
}
self.activitiesByDate = grouped
self.calendarView.reloadData()
} catch {
showError("Could not load activities: \(error)")
}
Rendering Activities by Type
Each activity type carries different metadata. Use the type field to determine which details to display.
// Android -- render an activity card based on type
fun renderActivity(activity: Activity) {
titleLabel.text = activity.name
dateLabel.text = activity.date
statusIcon.setImageResource(statusIconFor(activity.statusType))
when (activity.type) {
ActivityType.GYM_VISIT_ACTIVITY -> {
subtitleLabel.text = activity.metaData?.facilityName
detailLabel.text = "${activity.metaData?.timeSpent ?: 0} min"
}
ActivityType.SMART_WALKING_ACTIVITY -> {
subtitleLabel.text = "${activity.metaData?.steps ?: 0} steps"
detailLabel.text = "${activity.metaData?.calories ?: 0} cal"
}
ActivityType.SELF_REPORTED_ACTIVITY -> {
subtitleLabel.text = activity.metaData?.facilityName
detailLabel.text = "Self-reported"
}
ActivityType.HOME_ACTIVITY -> {
subtitleLabel.text = "At-home workout"
detailLabel.text = activity.metaData?.description
}
else -> {
subtitleLabel.text = activity.message
}
}
}
Best Practices
- Query one month at a time. The API is calendar-based. To build a scrollable history, load each month as the user navigates backward.
- Color-code by status. Use distinct colors for accepted (green), pending (yellow), and rejected (red) activities in calendar and list views.
- Treat APPROVED, ACCEPTED, and COMPLETED as equivalent. The server may return any of these for verified activities. Normalize them in your UI logic.
- Show rejection reasons. When
statusTypeisDENIEDorREJECTED, displayactivity.messageso the member understands why. - Pull-to-refresh the current month, since activities can change as visits are verified or step data is processed.
Quick Reference
- Android (Kotlin)
- iOS (Swift)
// Android
AFCore.activities().get(month = 2, year = 2026) // Returns AFActivitiesSummary
// iOS
try await AFCore.shared.activities().get(month: 2, year: 2026)