Skip to main content

Overview

ActivityInsightsBuilder is an enum that provides static methods to build ActivityInsights from collections of Strava activities. It aggregates activity data into various metrics including heatmaps, streaks, weekly volumes, training rhythms, and peak performances.

Methods

build

Builds complete activity insights from an array of Strava activities.
public static func build(
    activities: [StravaActivity],
    windowEnd: Date = Date(),
    windowDays: Int = 366,
    weeksToShow: Int = 52,
    peakDayLimit: Int = 8,
    peakActivityLimit: Int = 12
) -> ActivityInsights

Parameters

activities
[StravaActivity]
required
Array of Strava activities to analyze. Activities outside the time window will be filtered out.
windowEnd
Date
default:"Date()"
End date of the analysis window. Defaults to the current date.
windowDays
Int
default:"366"
Number of days to include in the analysis window, counting backwards from windowEnd.
weeksToShow
Int
default:"52"
Number of weeks to display in the heatmap view.
peakDayLimit
Int
default:"8"
Maximum number of peak days to include in the results.
peakActivityLimit
Int
default:"12"
Maximum number of peak activities to include in the results.

Returns

ActivityInsights
ActivityInsights
A comprehensive insights object containing aggregated metrics and analytics.

Example

import StratilesCore

// Fetch activities from Strava
let activities: [StravaActivity] = await stravaClient.fetchActivities()

// Build insights for the past year
let insights = ActivityInsightsBuilder.build(
    activities: activities,
    windowEnd: Date(),
    windowDays: 365,
    weeksToShow: 52,
    peakDayLimit: 10,
    peakActivityLimit: 15
)

// Access computed metrics
print("Total miles: \(insights.totalMiles)")
print("Current streak: \(insights.currentStreakDays) days")
print("Longest streak: \(insights.longestStreakDays) days")
print("Total activities: \(insights.totalActivities)")

// Display peak performance
for peakDay in insights.peakDays {
    print("\(peakDay.date): \(peakDay.miles) miles")
}

// Analyze training patterns
for rhythmCell in insights.trainingRhythm {
    print("Weekday \(rhythmCell.weekday) at hour \(rhythmCell.hour): \(rhythmCell.activityCount) activities")
}

buildPartial

Builds partial activity insights from pre-computed heatmap data. This method provides limited insights when full activity data is unavailable.
public static func buildPartial(
    heatmapDays: [HeatmapDay],
    windowEnd: Date = Date(),
    windowDays: Int = 366,
    weeksToShow: Int = 52,
    peakDayLimit: Int = 8
) -> ActivityInsights

Parameters

heatmapDays
[HeatmapDay]
required
Pre-computed daily activity aggregations
windowEnd
Date
default:"Date()"
End date of the analysis window
windowDays
Int
default:"366"
Number of days to include in the analysis window
weeksToShow
Int
default:"52"
Number of weeks to display in the heatmap view
peakDayLimit
Int
default:"8"
Maximum number of peak days to include

Returns

ActivityInsights
ActivityInsights
A partial insights object with isPartial set to true. The following fields will have default/empty values:
  • totalMovingHours: 0
  • totalElevationGainMeters: 0
  • totalKudos: 0
  • trainingRhythm: empty array
  • maxRhythmCount: 0
  • typeBreakdown: empty array
  • peakActivities: empty array
  • pacePoints: empty array
  • effortPoints: empty array
  • weeklyEffort: empty array

Example

import StratilesCore

// Use pre-computed heatmap data
let heatmapDays: [HeatmapDay] = loadCachedHeatmap()

// Build partial insights
let insights = ActivityInsightsBuilder.buildPartial(
    heatmapDays: heatmapDays,
    windowEnd: Date(),
    windowDays: 365
)

// Access available metrics
print("Total miles: \(insights.totalMiles)")
print("Total activities: \(insights.totalActivities)")
print("Current streak: \(insights.currentStreakDays) days")

// Note: Partial builds have limited data
print("Is partial: \(insights.isPartial)") // true

Notes

  • All distance values are converted from meters to miles using the conversion factor 1609.344 meters per mile
  • Elevation gain is converted from meters to feet using the conversion factor 3.28084 feet per meter
  • Activities are filtered by local start date to ensure correct timezone handling
  • Training rhythm uses UTC calendar to properly extract hour and weekday from Strava’s local time format
  • Pace points only include activities with distance > 500 meters and positive moving time
  • Effort points only include activities with available suffer scores
  • Streaks count consecutive days with at least one activity

Build docs developers (and LLMs) love