iOS 7 определяет, доступен ли истинный северный курс

У меня есть приложение, которое я недавно преобразовал в использование нового API компаса от Apple. Раньше использовались старые (теперь устаревшие) API.

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

    if ( [CLLocationManager headingAvailable] )
    {
        if ( [CLLocationManager locationServicesEnabled] )
            [motionMgr startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXTrueNorthZVertical];
        else
            [motionMgr startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXMagneticNorthZVertical];
    }

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

Кто-нибудь знает предпочтительный способ определить, может ли система получить истинный север? Я мог бы использовать класс Reachability, но это может быть излишним. Он все еще может определить истинный север из-за кэшированного значения.

[Редактировать]

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

[motionMgr startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXTrueNorthZVertical];
// Call checkForTrueNorth a second or so after starting motion updates to see if true north is available
// It needs a bit of time to get running.  If it isn't available switch to using magnetic north.
[self performSelector:@selector(checkForTrueNorth) withObject:nil afterDelay:1.5];


- (void)checkForTrueNorth
{
if (motionMgr.deviceMotion == nil)  // nil means it couldn't get true north.
{
    [motionMgr stopDeviceMotionUpdates];
    [motionMgr startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXMagneticNorthZVertical];
}
}

Меня беспокоит только этот метод: я не думаю, что в этом случае задокументировано поведение, возвращающее nil. Это работает сейчас, но, возможно, не в будущих версиях.


person btschumy    schedule 09.01.2014    source источник


Ответы (1)


В дополнение к режиму полета (который можно протестировать с помощью Reachability), другая основная причина, по которой истинный север недоступен, заключается в том, что этот системный параметр отключен:

Конфиденциальность / Службы определения местоположения / Системные службы / Калибровка компаса

Apple не предоставила возможности узнать об этом конкретном параметре. Тем не менее, вы можете проверить доступность истинного севера, посмотрев данные о курсе, сообщаемые устройством, например, следующим образом:

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading 
{
BOOL trueHeadingUnavailable =  (newHeading.trueHeading < 0.0 && newHeading.magneticHeading >= 0.0)
...
}
person gpdawson    schedule 03.06.2015