2017-05-29 26 views
1

我有一個HKObserverQuery安裝程序在後臺獲取步驟(enableBackgroundDelivery方法在application:didFinishLaunchingWithOptions:中調用)。使用HealthKit的後臺傳遞檢索步驟後將數據寫入Firebase

這些步驟在後臺檢索,但我也想將檢索到的步驟存儲在Firebase數據庫中。雖然這部分失敗,但沒有任何內容存儲在Firebase中。當應用程序處於前臺時,存儲這些步驟的方法可以正常工作。值得讚賞的是,有關如何在後臺成功編寫Firebase數據的任何想法。

class HealthKitManager { 

    static let shared = HealthKitManager() 
    private let healthStore = HKHealthStore() 
    private let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)! 

    private init() { 

    } 

    func getTodaysStepCount(completion: @escaping (Double) -> Void) { 
     let now = Date() 
     let startOfDay = Calendar.current.startOfDay(for: now) 
     let predicate = HKQuery.predicateForSamples(withStart: startOfDay, end: now, options: .strictStartDate) 

     let query = HKStatisticsQuery(quantityType: stepsQuantityType, quantitySamplePredicate: predicate, options: .cumulativeSum) { (_, result, error) in 
      var resultCount = 0.0 

      guard let result = result else { 
       log.error("Failed to fetch steps = \(error?.localizedDescription ?? "N/A")") 
       completion(resultCount) 
       return 
      } 

      if let sum = result.sumQuantity() { 
       resultCount = sum.doubleValue(for: HKUnit.count()) 
      } 

      DispatchQueue.main.async { 
       completion(resultCount) 
      } 
     } 

     healthStore.execute(query) 
    } 

    func enableBackgroundDelivery() { 
     let query = HKObserverQuery(sampleType: stepsQuantityType, predicate: nil) { [weak self] (query, completionHandler, error) in 
      if let error = error { 
       log.error("Observer query failed = \(error.localizedDescription)") 
       return 
      } 

      self?.getTodaysStepCount(completion: { steps in 
       // Store steps using Firebase: 
       StepsManager.shared.updateUserSteps(steps) 
       completionHandler() 
      }) 
     } 

     healthStore.execute(query) 
     healthStore.enableBackgroundDelivery(for: stepsQuantityType, frequency: .hourly) { (success, error) in 
      log.debug("Background delivery of steps. Success = \(success)") 

      if let error = error { 
       log.error("Background delivery of steps failed = \(error.localizedDescription)") 
      } 
     } 
    } 

} 

回答

4

好的,我解決了這個問題。問題是我正在調用completionHandler,告訴HealthKit我完成了我的操作,然後實際完成了對Firebase的保存。保存到Firebase是異步完成的。

我添加了一個完成處理程序StepsManager.shared.updateUserSteps功能:

func updateUserSteps(_ steps: Double, withCompletion completion: (() -> Void)? = nil) { 
    let stepsReference = databaseInstance.reference(withPath: stepsPath) 
    stepsReference.setValue(steps) { (error, _) in 
     if let completion = completion { 
      completion() 
     } 
    } 
} 

databaseRef.setValue完成時被觸發。然後,我將觀察者查詢更新爲以下內容:

self?.getTodaysStepCount(completion: { steps in 
    StepsManager.shared.updateUserSteps(steps) { 
     completionHandler() 
    } 
}) 

Firebase操作現在完成。

相關問題