5

Здравствуйте, я пытаюсь настроить наблюдателя магазина работоспособности с включенной доставкой фона. Моя проблема в том, что он ничего не будет делать, когда экран заблокирован. Я упростил свой код для этого вопроса, чтобы добраться до точки :) У меня есть HealthKit в моем plist, и я принял счет шага типа HealthStore. Все в порядке, когда приложение открыто и когда экран не заблокирован. Но когда экран заблокирован, я не получаю никаких наблюдений. Для целей тестирования частота установлена ​​на немедленную.HealthStore enableBackgroundDelivery, когда экран заблокирован

Мой код выглядит следующим образом

- (void)setupHealthStore{ 
if ([HKHealthStore isHealthDataAvailable]) 
{ 
    NSSet *readDataTypes = [self dataTypesToRead]; 
    self.healthStore = [[HKHealthStore alloc]init]; 
    [self.healthStore requestAuthorizationToShareTypes:nil readTypes:readDataTypes completion:^(BOOL success, NSError *error) 
    { 
     if (success) 
     { 
      HKQuantityType *quantityType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]; 
      [self.healthStore enableBackgroundDeliveryForType:quantityType frequency:HKUpdateFrequencyImmediate withCompletion:^(BOOL success, NSError *error) 
      { 
       if (success) 
       { 
        [self setupObserver]; 
       } 
      }]; 
     } 
    }]; 
} 

}

Описанный выше метод вызывается в AppDelegate didfinishLaunchWithOptions

Следующий метод

- (void)setupObserver{ 
HKQuantityType *quantityType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]; 
HKObserverQuery *query = [[HKObserverQuery alloc]initWithSampleType:quantityType predicate:nil updateHandler:^(HKObserverQuery *query, HKObserverQueryCompletionHandler completionHandler, NSError *error) 
{ 
    if (!error) 
    { 
     [self alarm]; 
     if (completionHandler) 
     { 
      NSLog(@"Completed"); 
      completionHandler(); 
     } 
    } 
    else 
    { 
     if (completionHandler) 
     { 
      completionHandler(); 
     } 
    } 
}]; 
[self.healthStore executeQuery:query]; 

}

Когда я открываю приложение, он немедленно возвращает наблюдение.

+0

Посмотрите на мой ответ здесь: http://stackoverflow.com/a/35073904/1677480 – damirstuhec

ответ

2

Я смог заставить это работать, наблюдая за весом и изменениями глюкозы в крови HealthKit.

В ApplicationDelegate:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 
    // Override point for customization after application launch.   

    GlobalHealthManager.startObservingWeightChanges() 

    return true 
} 

HealthManager.swift

let past = NSDate.distantPast() as NSDate 
    let now = NSDate() 
    return HKQuery.predicateForSamplesWithStartDate(past, endDate:now, options: .None) 

    }() 

    //here is my query: 
    lazy var query: HKObserverQuery = {[weak self] in 
    let strongSelf = self! 
    return HKObserverQuery(sampleType: strongSelf.weightQuantityType, 
     //predicate: strongSelf.longRunningPredicate, 
     predicate : nil, //all samples delivered 
     updateHandler: strongSelf.weightChangedHandler) 
    }() 




func startObservingWeightChanges(){ 
     healthKitStore?.executeQuery(query) 
     healthKitStore?.enableBackgroundDeliveryForType(weightQuantityType, 
      frequency: .Immediate, 
      withCompletion: {(succeeded: Bool, error: NSError!) in 

      if succeeded{ 
       println("Enabled background delivery of weight changes") 
      } else { 
       if let theError = error{ 
        print("Failed to enable background delivery of weight changes. ") 
        println("Error = \(theError)") 
       } 
      } 

    }) 
} 



/** this should get called in the background */ 
func weightChangedHandler(query: HKObserverQuery!, 
    completionHandler: HKObserverQueryCompletionHandler!, 
    error: NSError!){ 

     NSLog(" Got an update Here ") 

    /** this function will get called each time a new weight sample is added to healthKit. 

    //Here, I need to actually query for the changed values.. 
    //using the standard query functions in HealthKit.. 

     //Tell IOS we're done... updated my server, etc. 
     completionHandler()   
} 


} 
+0

Я должен отметить, что это работает даже тогда, когда приложение не работает, при условии, что у вас есть правильные разрешения. – cmollis

+0

Благодарим вас за ответ. Можете ли вы действительно запросить у HealthStore данные?Потому что согласно документам HealthStore защищен, когда экран заблокирован. С заблокированным я имею в виду заблокированный с кодом доступа. В любом случае это хорошо, если он работает, но мне нужен он для типа данных шага. – Thomas

+0

Да, я могу запросить данные с помощью API запросов HK. Я запутался в проблеме с паролем. Если экран заблокирован, и ваше приложение (или любое другое приложение записывает эти данные) может записать шаги в базу данных HK, тогда я думаю, что фоновые наблюдатели будут работать. – cmollis

0

Шаги имеют минимальную частоту обновления 1 час, что означает, что ваше приложение будет только разбудить один раз/час. После того как вы откроете приложение, ваши запросы наблюдателей сразу будут уволены. См. Примечание в обсуждении для enableBackgroundDeliveryForType.

https://developer.apple.com/library/prerelease/ios/documentation/HealthKit/Reference/HKHealthStore_Class/index.html#//apple_ref/occ/instm/HKHealthStore/enableBackgroundDeliveryForType:frequency:withCompletion:

+0

Я читал это немного по-другому, я понимаю минимальную частоту обновления, так как я должен как минимум получать его один раз в час, я могу получить его немедленно, если захочу, но я не могу установить минимум на что-либо более одного раза в час, например, один раз в день не допускается. У меня есть testet это, и я сразу получаю шаги, когда устанавливаю частоту. – Thomas

+0

Что ж, ваши эксперименты не выдерживают этого? Ваше приложение сразу проснулось или раз в час? – drdaanger

+0

Наблюдатель получает уведомление немедленно, но только если приложение пробуждается другими службами, такими как служба определения местоположения или выборка фона. – Thomas

0

В случае HKObserverQuery, вы должны включить любой из фоновых режимов приложения, чтобы получить уведомление для ObserverQuery в фоновом режиме (приложение не убили).

enter image description here

8

Когда iPhone заблокирован, вы не можете получить доступ к данным healthKit с каким-либо образом.

Когда iPhone разблокирован, но приложение находится в фоновом режиме, вы можете использовать только HKObserverQuery, который используется для определения того, добавлены или нет новые образцы.

Когда iPhone разблокирован и приложение находится на переднем плане, вы можете использовать все, что связано с HealthKit Framework.

+0

Это должен быть правильный ответ. HealthKit не может быть запрошен, если экран устройства выключен и установлен пароль (это называется заблокированным). – lehn0058

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