NSUserDefaultsDidChangeNotification не срабатывает после отправки stopUpdatingLocation в CLLocationManager

В настоящее время в этом iOS-приложении я добавил некоторый контроллер, который я написал в качестве наблюдателя для [NSNotificationCenter defaultCenter] для наблюдения за NSUserDefaultsDidChangeNotification.

- (void)startObservingDefaults
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(userDefaultsDidChange)
                                                 name:NSUserDefaultsDidChangeNotification
                                               object:nil];
}

Пользователь по умолчанию, который я наблюдаю, должен включать или отключать CLLocationManager с помощью PSToggleSwitchSpecifier в меню настроек. После запуска приложения и отправки startUpdatingLocation на CLLocationManager ивар я могу зайти в меню настроек и отключить менеджер местоположений. Затем мой селектор userDefaultsDidChange проверит, включено или отключено это значение по умолчанию. Если он включен, я отправляю startUpdatingLocation экземпляру менеджера местоположения, если он отключен, я отправляю ему stopUpdatingLocation. Каждый путь регистрирует свое действие следующим образом

- (void)userDefaultsDidChange
{
    if ([self duringOperationHours] && [self isEnabled]) {
        NSLog(@"\n\n\nWithin Operating Hours.\n\n\n");
        [_locationManager startUpdatingLocation];
        NSLog(@"Enabled Location Manager.");
    } else {
        NSLog(@"\n\n\nDisabled or Outside of Operating Hours.\n\n\n");
        [_locationManager stopUpdatingLocation];
        NSLog(@"Disabled Location Manager.");
    }
}

У меня есть другие настройки, которые контролируют время суток (время начала и время окончания, например, с 6:00 до 18:00). Если я изменю один из этих параметров, а текущее время все еще будет в пределах этого временного диапазона, в журнале будет указано, что оно все еще находится в режиме «В рабочие часы». и что диспетчер местоположений включен.

Если я изменю его так, чтобы диспетчер местоположений отключился, он зарегистрирует оба оператора NSLog в моем методе выше и ДЕЙСТВИТЕЛЬНО закроет диспетчер местоположений.

Проблема возникает, когда я пытаюсь запустить его обратно. Так сказать я в настройках и он включен. Я отключаю его, журнал показывает, что он отключен, и маленький значок GPS исчезает, если я затем снова включу его, уведомление вообще не срабатывает. На самом деле никакие другие настройки даже в других дочерних панелях не срабатывают, пока я не вернусь в приложение. (Я попробовал dispatch_async внутри метода userDefaultsDidChange как для main_queue, так и для global_queue и не увидел изменений).

МОЙ ВОПРОС: я делаю что-то не так, из-за чего это может заблокироваться в диспетчере местоположений? Или это какая-то внутренняя проблема с очередью для CLLocationManager? Или что-то другое? Возможно CLLocationManager запустится только если приложение на переднем плане? Даже если бы это было так, я должен по-прежнему видеть сообщения в журнале о том, что он по крайней мере попытался запустить менеджер местоположений, верно?


person Dean Kelly    schedule 28.01.2014    source источник


Ответы (1)


Неважно, я разобрался.

Наблюдение NSNotificationCenter за NSUserDefaultsDidChangeNotification НЕ не пробуждает приложение. Происходило то, что протокол CLLocationManagerDelegate, примененный к моему контроллеру, «разбудил» приложение, чтобы сделать то, что ему нужно, с полученными CLLocations. После этого пробуждения наблюдение за изменением некоторых пользовательских настроек по умолчанию в NSNotificationCenter приведет к срабатыванию моего селектора userDefaultsDidChange.

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

Я обновлю этот ответ, если найду лучшее решение для этого странного сценария наблюдения.

person Dean Kelly    schedule 28.01.2014
comment
извините за наезд. Вы поняли? Я в такой же ситуации... Спасибо. - person Fabio Mignogna; 16.09.2015
comment
Это ответ. Уведомления NSNotificationCenter не будут разбудить приложение для этого конкретного события. CLLocationManager пробуждал приложение и разрешал получение уведомления. После отключения вам придется вернуть приложение на передний план, чтобы получать события. - person Dean Kelly; 17.09.2015