4

我有一个应用程序,我最近转换为使用 Apple 的新指南针融合 API。它曾经使用较旧的(现已弃用)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 并不是记录在案的行为。它现在可以工作,但在未来的版本中可能不会。

4

1 回答 1

0

除了飞行模式(可以使用可达性进行测试)之外,真北不可用的另一个主要原因是此系统设置已禁用:

隐私/定位服务/系统服务/指南针校准

Apple 没有提供任何方法来查询此特定设置。但是,您可以通过查看设备报告的航向数据来测试真北是否可用,例如:

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading 
{
BOOL trueHeadingUnavailable =  (newHeading.trueHeading < 0.0 && newHeading.magneticHeading >= 0.0)
...
}
于 2015-06-03T22:36:10.147 回答