开发风水罗盘时,看起来最简单的部分 — “从传感器读取方位” — 反而花的时间最多。原因是:iOS 返回两种航向,而它们并不相同。
magneticHeading 与 trueHeading
CLHeading 同时提供两个属性。magneticHeading 以磁北为基准;trueHeading 以地理北为基准。二者之差称为磁偏角(magnetic declination),在越南约为 0–1°。听起来很小,但罗盘将圆周分为二十四山,每山 15° — 在山界处偏 1°,结论就完全不同。
传统风水以磁北为准:真正的罗盘就是一根磁针。所以应用必须使用 magneticHeading,而不是听起来更“精确”的 trueHeading。
trueHeading 返回 -1
另一个陷阱:在未授予定位权限时,trueHeading 会返回负值。如果直接渲染到屏幕上,用户看到罗盘显示“-1°”,只会以为应用坏了。
规则:在信任任何航向值之前,务必检查
headingAccuracy >= 0。
磁场干扰
磁场传感器会被一切金属或磁性物体干扰:MagSafe 手机壳、钢制桌面、混凝土里的钢筋。iOS 通过 headingAccuracy 报告干扰程度 — 数值越大越不可信。应用会在超过阈值时给出警告,而不是默默显示错误的读数。
读数平滑
原始数据会不停抖动。但滤波过头,指针就会迟钝:转动手机时指针慢半拍地跟在后面,体验非常糟糕。平衡点在于:使用短窗口滑动平均,当变化幅度较大(用户在刻意转动手机)时绕过滤波器。
几轮迭代之后:静止时指针稳定,转动时紧密跟随,并且绝不会自己“漂移” — 这是一个测量工具必须达到的底线。