Observe HealthKit data changes with locked iPhone by Face ID

Hi, I have tried to observe HealthKit data (workouts) with background delivery, but I am faced with a problem - updates don't come when iPhone is locked by Face ID. Everything works fine with an unlocked device. I didn't find any references in the documentations. Is this the expected behavior?

Code:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        HealthManager.shared.startObservingWorkouts {
            /*
            Don't receive updates
            */ 
        }
        
        return true
    }
}

class HealthManager {
    static let shared: HealthManager = .init()
    private let hkStore = HKHealthStore()
    
    init() { }
    
    func startObservingWorkouts(handleUpdates: @escaping ([HKWorkout]) -> Void) {
        hkStore.getRequestStatusForAuthorization(
            toShare: [],
            read: [.workoutType()])
        { [weak self] status, _ in
            guard status == .unnecessary else {
                return
            }
            
            let prediction = HKQuery.predicateForSamples(
                withStart: Date().startOfDay,
                end: Date().endOfDay,
                options: [.strictStartDate, .strictEndDate]
            )
            let query = HKObserverQuery(
                sampleType: .workoutType(),
                predicate: prediction,
                updateHandler: { [weak self] _, completionHandler, _ in
                    self?.getWorkouts {
                        handleUpdates($0 ?? [])
                        completionHandler()
                    }
                }
            )
            
            self?.hkStore.execute(query)
            self?.hkStore.enableBackgroundDelivery(
                for: .workoutType(),
                frequency: .immediate
            ) { _, error in
                print(error)
            }
        }
    }
    
    private func getWorkouts(handleResult: @escaping ([HKWorkout]?) -> Void) {
        let prediction = HKQuery.predicateForSamples(
            withStart: Date().startOfDay,
            end: Date().endOfDay,
            options: [.strictStartDate, .strictEndDate]
        )
        let query = HKSampleQuery(
            sampleType: .workoutType(),
            predicate: prediction,
            limit: HKObjectQueryNoLimit,
            sortDescriptors: nil
        ) { query, samples, error in
            if error != nil {
                return
            }
            
            guard let samples = samples else {
                fatalError("*** Invalid State: This can only fail if there was an error. ***")
            }
            
            guard let workouts = samples as? [HKWorkout] else {
                return
            }
            
            handleResult(workouts)
        }
        
        hkStore.execute(query)
    }
}

@main
struct HealthKitTestApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

Replies

The HealthKit datastore is inaccessible when the device is locked, so you will not get any updates at that time.