HKObserverQuery случайно вызывается дважды подряд

У меня есть проблема, которую я пытаюсь решить, я настроил HKObserveryQuery, который прекрасно работает и собирает новые данные для меня.

Проблема, однако, заключается в том, что иногда, когда я возвращаюсь в приложение Health и удаляю элемент после того, как я вручную добавил его в приложение Health, я замечаю HKObserverQuery Я два раза очень близко настраивал пожары, и я пытаюсь их решить, потому что я использую этот наблюдатель для последующей загрузки некоторых данных, и мне не нужен дубликат.

Буду признателен за любую предложенную помощь. Код:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [self setup];

    return YES;
}

- (void)setup
{
    if ([HKHealthStore isHealthDataAvailable])
    {
        self.healthStore = [[HKHealthStore alloc]init];

        NSSet *readTypes = [NSSet setWithObject:[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate]];

        [self.healthStore requestAuthorizationToShareTypes:nil
                                                 readTypes:readTypes
                                                completion:^(BOOL success, NSError *error)
         {
             if (!error && success)
             {
                 [self observeHR];

                 [self.healthStore enableBackgroundDeliveryForType:
                 [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate]
                 frequency:HKUpdateFrequencyImmediate withCompletion:^(BOOL success, NSError *error){}];
             }
         }];
    }
}

- (void)observeHR
{
    HKObserverQuery *query = [[HKObserverQuery alloc]initWithSampleType:[HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate]
                        predicate:nil
    updateHandler:^(HKObserverQuery *query, HKObserverQueryCompletionHandler completionHandler, NSError *error)
    {
        if (!error)
        {   
            // Randomly called twice *VERY* close together
            NSLog(@"Query");
            [self queryWithCompletionHandler:completionHandler];
        }
        else
        {
            if (completionHandler)
            {
                completionHandler();
            }
        }
    }];

    [self.healthStore executeQuery:query];
}

Вывод на консоль, обратите внимание на время: это происходит при удалении только одного элемента из приложения Health, что неверно.

2014-12-29 16:50:20.121 TestApp[174:5674] Query
2014-12-29 16:50:20.124 TestApp[174:5674] Query

2 ответа

Решение

Я полагаю, что теперь я исправил проблему, установив флаг BOOL, чтобы предотвратить вызов второго фальшивого HKObserverQuery, и исключив повторную обработку без всякой причины. Код:

- (void)observeHR
{
    HKObserverQuery *query = [[HKObserverQuery alloc]initWithSampleType:[HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate]
                        predicate:nil
    updateHandler:^(HKObserverQuery *query, HKObserverQueryCompletionHandler completionHandler, NSError *error)
    {
        if (!self.queryInProgress)
        {
            self.queryInProgress = YES;

            if (!error)
            {
                [self queryWithCompletionHandler:completionHandler];
            }
            else
            {
                self.queryInProgress = NO;

                if (completionHandler)
                {
                    completionHandler();
                }
            }
        }
        else
        {
            NSLog(@"Query already in progress");
        }
    }];

    [self.healthStore executeQuery:query];
}

Вы не должны проектировать систему, которая опирается на updateHandler из HKObserverQuery стрельба ровно один раз для любого конкретного события. Лечить призывы updateHandler просто как указание на то, что любое количество выборок, соответствующих предикату, могло быть добавлено или удалено. Вы должны выполнить запрос, чтобы узнать, что изменилось. Если, например, вас интересуют только новые выборки, соответствующие предикату, вы можете использовать HKAnchoredObjectQuery чтобы получить только образцы, которые вы еще не обработали.

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