设备端 AI 与空间计算为什么重要
把模型放在设备上跑,换来三件事:低延迟、离线可用、数据不出设备。对增强现实来说这几乎是硬要求——摄像头每帧都要推理,若走网络请求,画面延迟立刻就能被用户感知。ARKit 负责理解空间,Core ML 负责理解内容,Vision 把两者串起来。
AR 体验的分水岭不在特效,而在「稳不稳」:追踪抖动、锚点漂移、推理掉帧,任何一项都会让沉浸感瞬间消失。
- ARSession融合摄像头与传感器数据,输出设备位姿与世界锚点。
- RealityKit渲染虚拟内容,处理遮挡、阴影与光照估计。
- Vision + Core ML在帧上做检测与分类,把结果回填进 AR 空间。
- LiDAR提供深度信息,让平面检测与人物遮挡更可靠。
ARSession 与世界追踪
AR 应用的起点是一段配置正确的会话:调用 ARSession.run 并传入合适的 ARWorldTrackingConfiguration,会话就会持续输出帧(ARFrame)与锚点(ARAnchor)。
世界追踪配置以设备的初始位置为原点建立坐标系,后续所有虚拟物体都挂在这个坐标系下,因此追踪一旦漂移,所有内容都会跟着偏。开启水平与垂直平面检测,能让系统在扫描阶段同时识别地面与墙面;锚点与会话同生命周期,新增锚点时通过 ARSessionDelegate 的回调接收通知,即可据此提示用户「已识别到可用表面」。追踪质量高度依赖环境:光照均匀、纹理丰富、移动平缓时最稳,纯白墙面、镜面地面与快速旋转都会导致追踪降级。调试时打开 ARView.debugOptions = [.showFeaturePoints],能直观看到特征点是否充足。
平面检测与射线拾取
把虚拟物体放到真实桌面上,需要把屏幕上的二维坐标转换到三维空间。射线检测从触点发射一条射线,与已识别的平面或场景几何求交,返回世界坐标与表面法线;有了法线,就能让物体贴合表面朝向摆放,而不是歪斜地插进桌子里。
func handleTap(_ location: CGPoint, in arView: ARView) {
guard let hit = arView.raycast(from: location,
allowing: .estimatedPlane,
alignment: .horizontal).first else { return }
let box = ModelEntity(mesh: .generateBox(size: 0.12),
materials: [SimpleMaterial(color: .systemBlue)])
let anchor = AnchorEntity(world: hit.worldTransform)
anchor.addChild(box)
arView.scene.addAnchor(anchor)
}
.estimatedPlane 表示「还没完全识别,先按估计平面放置」,视觉上要配合引导动画,等平面真正识别后再吸附到位;.existingPlaneGeometry 只接受已确认的平面,更稳但要求用户多扫一会儿。两种策略按场景选择,室内家具摆放适合前者,需要精确贴合的场景适合后者。
Core ML:把模型跑在设备上
Core ML 接受 .mlpackage 格式的模型,可以直接从主流训练框架导出。模型加载后配合 Vision 的请求对象,就能在摄像头帧上做分类或检测,得到带置信度的结构化结果。整个推理过程在设备上完成,用户画面与数据都不会离开手机。
func classify(_ buffer: CVPixelBuffer, model: MLModel) -> String? {
guard let mlModel = try? VNCoreMLModel(for: model) else { return nil }
let request = VNCoreMLRequest(model: mlModel)
let handler = VNImageRequestHandler(cvPixelBuffer: buffer, orientation: .up)
try? handler.perform([request])
let top = (request.results as? [VNClassificationObservation])?.first
return top.map { "\($0.identifier) \(Int($0.confidence * 100))%" }
}
模型大小直接影响启动时间,请把它放在后台队列加载,并用 MLModelConfiguration 指定计算单元。推理频率也要控制,没必要每帧都跑,隔几帧采样一次通常足够,还能省下可观的电量与发热。
AR 与 ML 的组合场景
把两块能力接起来能做出不少实用的东西:识别货架上的商品并在其上方浮动标签、识别家具类型后按真实尺寸摆放在地面上、或者识别文字并即时翻译贴在原位。它们共同的技术套路是「Vision 给出二维检测框 → 用相机参数反投影到三维空间 → 生成跟随目标的锚点」。
- 给引导首次进入先用一句提示告诉用户如何移动设备完成扫描。
- 给反馈平面识别进度与放置成功都要有即时的视觉反馈。
- 给退路追踪受限时提示「光线不足,请缓慢移动」,而不是黑屏。
性能、权限与真机调试
AR 与 ML 都是重负载能力,模拟器基本无法完整验证,必须上真机测试,最低要求是 A12 及以上芯片,带 LiDAR 的机型在平面检测与人物遮挡上体验明显更好。测试时建议锁定屏幕亮度、关闭低电量模式,否则系统会主动降频,测出的帧率不具参考性。
权限方面,相机与麦克风的使用说明必须具体。NSCameraUsageDescription 不能只写「需要相机权限」,而要写清用途,例如「用于在相机画面中识别商品并叠加信息」,审核人员会逐条核对这类文案。
把帧率统计放在 ARSessionDelegate 的 didUpdate 回调里,用指数滑动平均抹平抖动,就能得到稳定可读的实时帧率;一旦 frame.camera.trackingState 不是 .normal,就立刻暂停高频推理,先把画面稳定性保住,而不是继续往渲染管线里塞内容。
真机实测掉帧时,优化顺序是:先降低推理频率,再降低模型输入分辨率,最后才考虑简化渲染内容。渲染往往是最后的瓶颈,先动它容易白忙一场,还可能牺牲视觉质量换不到帧率。
小结与延伸阅读
苹果的 AR 与 AI 能力已经在系统层打通:ARKit 提供稳定的空间坐标系,Core ML 提供可离线运行的模型,Vision 负责把两者串起来。掌握这条链路,就能做出许多不依赖云端的智能交互。
- Swift 语法不熟,先读《Swift 语言入门:iOS 开发第一步》。
- 界面部分读《SwiftUI 声明式 UI:从零构建界面》,AR 应用的设置页与结果页都要靠它。
- 要发布到商店,读《iOS 应用开发全流程:从 Xcode 到上架》,权限与隐私声明的部分尤其相关。
建议的第一个练习:做一个「扫描识别 + 浮动标签」的小工具,识别结果只做三类分类即可,目标是把会话管理、坐标转换与模型推理三件事都跑通一次。