2015-05-29 3 views
0

Я следил за Apple Docs и несколькими потоками в stackoverflow о том, как добиться фоновой выборки данных из магазина здоровья. До сих пор у меня есть:HealthKit Observer не работает, пока приложение находится в фоновом режиме

  • Добавлено HealthKit Entitlement к моему APPID
  • Добавлено Необходимые предпосылки Режимы
  • Добавлен код AppDelegate.swift, как Apple, предполагают (фрагмент кода ниже является не следуя ООП только для того, чтобы заявить об этом здесь)

Это мой код (быстрый): Если ваш ответ находится в Obj-C и работает, пожалуйста, укажите его также, мне придется его перевести, но это не проблема.

AppDelegate.swift

var healthStore: HKHealthStore? 
var bpmSamples: [HKQuantitySample]? 

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 
    let dataTypesToWrite = [ ] 
    let dataTypesToRead = [ 
     HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate), 
     HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMassIndex), 
     HKCharacteristicType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierDateOfBirth) 
    ] 
    if self.healthStore == nil { 
     self.healthStore = HKHealthStore() 
    } 
    self.healthStore?.requestAuthorizationToShareTypes(NSSet(array: dataTypesToWrite as [AnyObject]) as Set<NSObject>, 
     readTypes: NSSet(array: dataTypesToRead) as Set<NSObject>, completion: { 
      (success, error) in 
      if success { 
       self.addQueryObserver() 
       println("User completed authorisation request.") 
      } else { 
       println("The user cancelled the authorisation request. \(error)") 
      } 
    }) 
    return true 
} 

func addQueryObserver(){ 
    let sampleType = 
    HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate) 

    let query = HKObserverQuery(sampleType: sampleType, predicate: nil) { 
     query, completionHandler, error in 
     if error != nil { 
      // Perform Proper Error Handling Here... 
      println("*** An error occured while setting up the stepCount observer. \(error.localizedDescription) ***") 
      abort() 
     } 
     println("query is running") 

     self.performQueryForHeartBeatSamples() 
     completionHandler() 
    } 
    healthStore?.executeQuery(query) 
    healthStore?.enableBackgroundDeliveryForType(sampleType, frequency:.Immediate, withCompletion:{ 
     (success:Bool, error:NSError!) -> Void in 
     let authorized = self.healthStore!.authorizationStatusForType(sampleType) 
     println("HEALTH callback success", success) 
     println("HEALTH callback authorized", sampleType) 
    }) 
    if HKHealthStore.isHealthDataAvailable() == false { 
     println("HEALTH data not available") 
     return 
    } else { 
     println("HEALTH OK") 
     self.performQueryForHeartBeatSamples() 
    } 
} 
// MARK: - HealthStore utility methods 
func performQueryForHeartBeatSamples() { 
    let endDate = NSDate() 
    let startDate = NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitMonth, value: -2, toDate: endDate, options: nil) 

    var heartRate : HKQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate) 

    let predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: endDate, options: .None) 
    let query = HKSampleQuery(sampleType: heartRate, predicate: predicate, limit: 0, sortDescriptors: nil, resultsHandler: { 
     (query, results, error) in 
     if results == nil { 
      println("There was an error running the query: \(error)") 
     } 
     dispatch_async(dispatch_get_main_queue()) { 
      self.bpmSamples = results as? [HKQuantitySample] 
      let heartRateUnit: HKUnit = HKUnit.countUnit().unitDividedByUnit(HKUnit.minuteUnit()) 
      if self.bpmSamples?.count > 0 { 
       if let sample = self.bpmSamples?[self.bpmSamples!.count - 1] { 
        println(sample.quantity!.description) 
        let quantity = sample.quantity 
        var value = quantity.doubleValueForUnit(heartRateUnit) 
        println("bpm: \(value)") 
       } 
      } 
      else { 
       println("No Data") 
      } 
     } 
    }) 
    self.healthStore?.executeQuery(query) 
} 

Таким образом, проблема заключается в том, что я получаю только обновления, когда я возвращаюсь приложение из фона в активное состояние вручную .. HKObserverQuery не кажется, работая для меня в фоновом режиме.

Любые предложения?

+0

Вы отладки на устройстве и вручную смоделировали фон выборки из меню Debug? –

+0

Я тестировал его как на реальных, так и на симуляторных устройствах. В обоих случаях я добавляю новые данные вручную в HealthKit и ждал, что 'HKObserverQuery' сделает свое mojo. Я только что проверил этот фоновый выбор и ничего не сделал. –

+0

Он не будет работать на симуляторе, вам нужно смоделировать фоновый выбор на реальном устройстве, вы попробовали это? –

ответ

1

В моем опыте частота «.Immediate» не работает. Обработчик запросов вставляется в фоновый режим. Если совпадающие сэмплы часто добавляются или iOS занят, немедленная частота не работает.

Кроме того, вы не можете использовать HKSampleQuery в HKObserverQuery. updateHandlerHKObserverQuery может работать, но HKSampleQuery не будет. Обработчик запроса наблюдателя может быть выполнен в фоновом режиме, но один из примерного запроса не может быть выполнен в фоновом режиме.

Вы должны знать, что ТОЛЬКОHKObserverQuery можно использовать в фоновом режиме

+0

Где вы нашли эту информацию: «Вы не можете использовать HKSampleQuery в HKObserverQuery»? – user3352495

+0

@ user3352495 Это было слишком давно, поэтому я не помню точное положение предложений. Тем не менее, я помню, что только HKObserverQuery среди всех API-интерфейсов о HealthKit может использоваться в фоновом режиме. Когда версия ОС повышается, она может отличаться от старой версии HealthKit, но в духе разработчика Apple не хочет, чтобы приложение использовало фоновые ресурсы. Поэтому, я думаю, он может быть таким же. –

 Смежные вопросы

  • Нет связанных вопросов^_^