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

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

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

РЕДАКТИРОВАТЬ: Фоновые режимы также реализован. Я проверил выборку фона. Все еще не работает ...

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

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 Ответ

0 голосов
/ 25 марта 2020

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

...