我有一个应用程序,我最近转换为使用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是记录的行为。它现在可以使用,但可能不会在将来的版本中使用。
答案 0 :(得分:0)
除了飞行模式(可以使用可达性进行测试)之外,真北不可用的另一个主要原因是此系统设置已被禁用:
隐私/定位服务/系统服务/指南针校准
Apple没有提供任何方式来询问此特定设置。但是,您可以通过查看设备报告的标题数据来测试真北,例如,如下所示:
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
BOOL trueHeadingUnavailable = (newHeading.trueHeading < 0.0 && newHeading.magneticHeading >= 0.0)
...
}