Contents

HKAnchoredObjectQueryDescriptor

A query interface that runs anchored object queries using Swift concurrency.

Declaration

struct HKAnchoredObjectQueryDescriptor<Sample> where Sample : HKSample

Mentioned in

Overview

Use HKAnchoredObjectQueryDescriptor to read any changes to the HealthKit store that occurred after the provided anchor. When creating a new query descriptor, if you pass nil as the anchor parameter, the query reads all matching data from the store.

There are two common use cases for anchored object queries:

Batch Read Existing Data

Users may have large quantities of data saved to the HealthKit store; therefore, reading all data for a given data type might become very expensive, both in terms of memory usage and processing time. To avoid performance issues, you can use HKAnchoredObjectQueryDescriptor queries to read the data in batches.

Start with a nil-valued anchor, and create a one-shot query descriptor that reads a batch of data. After you process the results from one query, start a new one-shot query for the next batch. Continue reading batches until there’s no new data.

let stepType = HKQuantityType(.stepCount)

// Start by reading all matching data.
var anchor: HKQueryAnchor? = nil
var results: HKAnchoredObjectQueryDescriptor<HKQuantitySample>.Result


repeat {
    // Create a query descriptor that reads a batch
    // of 100 matching samples.
    let anchorDescriptor =
    HKAnchoredObjectQueryDescriptor(
        predicates: [.quantitySample(type: stepType)],
        anchor: anchor,
        limit: 100
    )

    results = try await anchorDescriptor.result(for: store)
    anchor = results.newAnchor
    
    // Process the batch of results here.
    
} while (results.addedSamples != []) && (results.deletedObjects != [])

Monitor for Changes

To monitor the HealthKit store for changes, start by creating an HKAnchoredObjectQueryDescriptor instance that matches the data you want to monitor. Pass in the anchor from the last time you read data from the HealthKit store.

Next, call the query descriptor’s results(for:) method to start your long-running query. This method returns an AsyncSequence instance which HealthKit uses to return Results/Element instances. The first result represents any changes currently in the HealthKit store, and additional results represent changes as they occur.

let stepType = HKQuantityType(.stepCount)

// Create a query descriptor.
let anchorDescriptor =
HKAnchoredObjectQueryDescriptor(
    predicates: [.quantitySample(type: stepType)],
    anchor: anchor
)

let updateQueue = anchorDescriptor.results(for: store)

updateTask = Task {
    for try await update in updateQueue {
        // Process the update here.
        print(update)
    }
}

Topics

Creating Query Descriptors

Running Queries

Accessing Query Properties

Default Implementations

See Also

Long-running queries