Запросы Healthkit не работают, когда приложение находится в фоновом режиме

Мне нужно наблюдать данные о частоте пульса в Healthkit, а затем соответствующим образом отправить уведомление пользователю. Код работает нормально, но каждый раз мне приходится выводить приложение на передний план, чтобы иметь возможность получать уведомления. Мне нужно, чтобы это работало постоянно. Похоже, запросы не работают в фоновом режиме.

Я проверил почти все в Интернете, но не смог найти решение, которое мне нужно. Любая помощь будет оценена по достоинству!

EDIT: также реализованы фоновые режимы. Я проверил выборку фона. Все еще не работает...

Я добавил фрагменты своего кода ниже:

func requestHealthKitPermission(successCallback: @escaping () -> Void) {
    let sampleType: Set<HKSampleType> = [HealthKitService.heartRateType]
    let healthKitStore = HKHealthStore()

    healthKitStore.requestAuthorization(toShare: sampleType, read: sampleType) { (success, error) in

        if success {
            successCallback()
            self.startObservingNewHeartRates()

        }

        if let error = error {
            print("Error requesting health kit authorization: \(error)")
        }
    }
}

func startObservingNewHeartRates() {
    // open observer query

    let query = HKObserverQuery(sampleType: HealthKitService.heartRateType,
                                predicate: nil) { (query, completionHandler, error) in
                                    DispatchQueue.main.async {
                                        self.updateHeartRates(completionHandler: completionHandler)

                                    }
    }
    healthKitStore.execute(query)
    //  Enable background delivery
    healthKitStore.enableBackgroundDelivery(for: HealthKitService.heartRateType, frequency: .immediate) { (success, error) in
        if let error = error {
            print("could not enable background delivery: \(error)")
        }
        if success {
            print("background delivery enabled")
        }
    }

}
func updateHeartRates(completionHandler: @escaping () -> Void) {

    var anchor: HKQueryAnchor?

    if let data = UserDefaults.standard.object(forKey: Constants.UserDefaults.HEART_RATE_ANCHOR_KEY) as? Data {
        anchor = try? NSKeyedUnarchiver.unarchivedObject(ofClass: HKQueryAnchor.self, from: data)
    }

    let sampleType =  HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate)!
    let anchoredQuery = HKAnchoredObjectQuery(type: sampleType, predicate: nil, anchor: anchor, limit: HKObjectQueryNoLimit) {  query, newSamples, deletedSamples, newAnchor, error in

        self.handleNewHeartRates(new: newSamples!, deleted: deletedSamples!)

        if let newAnchor = newAnchor {
            let data = try? NSKeyedArchiver.archivedData(withRootObject: newAnchor, requiringSecureCoding: false)
            UserDefaults.standard.set(data, forKey: Constants.UserDefaults.HEART_RATE_ANCHOR_KEY)
            print("Wrote new Anchor")
        }

        completionHandler()
    }
    healthKitStore.execute(anchoredQuery)
}

func handleNewHeartRates(new: [HKSample], deleted: [HKDeletedObject]) {

    let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .short
    dateFormatter.timeStyle = .full

    let mapped = new.map { (sample) -> String? in
        guard let hrSample: HKQuantitySample = sample as? HKQuantitySample else { return nil }

        let heartRate = hrSample.quantity.doubleValue(for: HealthKitService.heartRateUnit)

        if heartRate >= 70 { // TODO: extract to Constants
            DispatchQueue.main.async {
                self.viewController?.setupHeartRateNotifications()

            }
        }
        return "\(heartRate)bpm @ \(dateFormatter.string(from: hrSample.startDate)) "
    }.compactMap { $0 }

    print(" ❤❤❤❤❤ new heartRate")
    mapped.forEach { (line) in
        print(line)
    }

    if let latestRecording = new.last {
        let formattedDate = dateFormatter.string(from: latestRecording.endDate)
        UserDefaults.standard.set(formattedDate, forKey: Constants.UserDefaults.LATEST_HEART_RATE_RECORDING_DATE_KEY)
    }
}

}

1 ответ

Попробуйте добавить возможности фоновых режимов и установите флажки Фоновая обработка и фоновая выборка. Надеюсь, что это работает.

Другие вопросы по тегам