A query that performs multiple statistics queries over a series of fixed-length time intervals, and returns the results.
- iOS 8.0+
- Mac Catalyst 13.0+
- watchOS 2.0+
Statistics collection queries are often used to produce data for graphs and charts. For example, you might create a statistics collection query that calculates the total number of steps for each day or the average heart rate for each hour. Like observer queries, collection queries can also act as long-running queries, receiving updates when matching samples are added to or removed from the HealthKit store.
Statistics collection queries use an anchor point and a time interval to partition the set of matching samples into collections. The anchor point defines an arbitrary starting point. The position of this point often does not matter. It could be in the future or in the past. Time intervals will extend away from this anchor point in both directions.
For example, if you use a 1-day time interval, the anchor point defines the time when each collection begins. The exact date for the anchor point doesn’t matter. It could be 3:34 am, January 1, 1970 or 3:34 am, March 15, 2065. In both cases, the statistics collection query partitions the matching samples into days, starting each day at 3:34 am.
You can use statistics collection queries only with quantity samples. If you want to calculate statistics over workouts or correlation samples, you must perform the appropriate query and process the data yourself.
Statistics collection queries are mostly immutable. You can assign the query’s
statistics properties after instantiating the object. All other properties must be set when you instantiate the object, and they cannot change.
For more information about statistics queries, see
Executing Statistics Queries
You create a sample query by calling the
statistics initializer. After the query is instantiated, you run it by calling the health store’s
execute(_:) method. This method runs the query on a anonymous background queue. When the query is complete, it executes the results handler on the same background queue (but not necessarily on the same thread). Typically, you dispatch these results back to the main queue to update your user interface.
The following sample code shows how to build a statistics collection query and process the results.
This sample demonstrates calculating per-week step totals using a statistics collection query. This code starts by creating a 1-week time interval. Next, it sets the anchor date to Monday morning at 3:00 a.m. Because the interval is 1 week long, the anchor’s exact date doesn’t matter. Each set of statistics represents exactly 1 week, starting on Monday at 3:00 a.m.
Next, the sample creates the quantity type for step counts and then creates the query itself. In contrast with how you create other queries, you do not set the callback block when you instantiate a statistics collection query. Instead, you can either set the initial result handler or the statistics update handler (or both) as needed for your app. In this case, the sample code just sets the initial results handler, letting it calculate statistics over the samples currently stored in HealthKit.
Inside the result handler’s block, the code checks to see whether an error has occurred. If it doesn’t find an error, it calculates the start and end times for a 3-month window and then iterates over all the time intervals in that window. The statistics collection passes the enumeration block a statistics object for each time interval between the start and end dates. However, if the time interval does not contain any samples, the provided statistics’s
sum method returns
nil. Therefore, the sample must check to see whether it has a valid quantity. If it does, it plots the data; otherwise, it simply skips that time interval.
Since we did not provide an update results handler, when the initial results block is done processing the data, the query stops automatically. If we had provided an update manager, the statistics collection query would continue to monitor the HealthKit store after it had generated the initial results.
After the sample defines the result handler’s block, the query is complete. The sample code simply executes this query using the HealthKit store.