其他
iOS 相机 App 接入 DockKit…
当需要在 iOS 视频/相机 App 中连接 DockKit 兼容的电动云台,实现人脸/人体自动追踪、自定义 ML 追踪、pan/tilt 电机控制、取景与感兴趣区域配置、配件按键和电池状态读取时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 35/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 39/100 ×0.15
适用场景
iOS 相机 App 接入 DockKi特定
解决思路
- 在需要 DockKit 的文件中 `import DockKit`;框架会自动通过 DockKit 系统守护进程与已配对配件通信,本身不需要特殊 entitlement 或 DockKit 专用 Info.plist 键;使用相机仍需正常的相机隐私处理(如 `NSCameraUsageDescription`)。
- 用 `DockAccessoryManager.shared.accessoryStateChanges` 异步序列观察配件连接:在 `.docked` 分支取 `stateChange.accessory` 并配置配件,在 `.undocked` 分支处理 iPhone 被取下,并补 `@unknown default`。
- 通过 `accessory.identifier` 读取配件的名称、类别与 UUID,通过 `firmwareVersion` 和 `hardwareModel` 获取硬件细节。
- 用 `try await DockAccessoryManager.shared.setSystemTrackingEnabled(true/false)` 显式启用/禁用系统跟踪;该状态不跨应用终止、重启或前后台切换保留,因此每次需要特定值都要重新设置(例如在 `applicationDidBecomeActive` 中重新设置)。
- 系统跟踪下支持点选主体:`accessory.selectSubject(at: CGPoint)` 按视频帧单位坐标选择主体,`selectSubjects([subjectUUID])` 按标识符选择,`selectSubjects([])` 清空选择回到自动选择。
- 自定义跟踪时先 `setSystemTrackingEnabled(false)`,用自定义 ML 模型或 Vision 推理结果构造 `DockAccessory.Observation`,并以 10-30 fps 调用 `accessory.track(_:cameraInformation:)`(挂到 `AVCaptureVideoDataOutputSampleBufferDelegate` 逐帧调用)。
- 构造 `DockAccessory.CameraInformation` 时从活跃 `AVCaptureDevice`(`deviceType`、`position`)和当前 `CMSampleBuffer`(`cameraIntrinsics`、`referenceDimensions`)内联构建,不要硬编码占位设备、内参或帧尺寸;当坐标已相对左下角时把 `orientation` 设为 `.corrected`。
- `DockAccessory.Observation.ObservationType` 只支持 `.humanFace`、`.humanBody`、`.object`,按检测类型显式选择,不要只写 `.humanFace`。
- `Observation.rect` 使用以左下角为原点的归一化坐标(与 Vision 框架坐标系一致,无需转换)。
- `track` 也可接受 `[AVMetadataObject]` 代替 observations;当需要 DockKit 把观测/元数据与捕获的图像缓冲合并时,使用带 `image: CVPixelBuffer` 的重载(该重载必须提供 image 参数)。
- 用 `accessory.setFramingMode(_:)` 控制取景:`.automatic`(文档默认,系统决定最佳取景)、`.center`(需显式选择的居中模式)、`.left`/`.right`(主体置于左/右三分处,当画面有图形叠加占用空间时使用);注意 `.center` 不是默认模式。
- 用 `accessory.setRegionOfInterest(CGRect)` 把跟踪限制在画面特定区域,坐标为左上原点的归一化坐标;在裁剪成非标准宽高比(如会议用方形视频)时使用,确保主体留在可见区域。
- 直接控制电机前必须先 `setSystemTrackingEnabled(false)`,否则系统跟踪会与手动指令相互冲突。
- 用 `accessory.setAngularVelocity(Vector3D)` 设置连续角速度(弧度/秒;`setAngularVelocity(Vector3D())` 停止所有运动);轴含义:`x`=pitch(iOS 上正值向下)、`y`=yaw(正值向右)、`z`=roll(若硬件支持)。
- 用 `accessory.setOrientation(target, duration:, relative:)` 在指定时长内移动到目标位置(也接受 `Rotation3D` 四元数);`relative: true` 表示相对当前位置移动,返回的 `Progress` 用于跟踪完成情况。
- 通过 `accessory.motionStates` 异步序列监控当前角度位置 `angularPositions`、角速度 `angularVelocities`、`timestamp` 以及 `error`(电机错误)。
- 用 `accessory.setLimits(_:)` 限制每轴运动范围与最大速度,例如构造 `DockAccessory.Limits.Limit(positionRange: -1.0 ..< 1.0, maximumSpeed: 0.5)`,未限制的轴传 `nil`(如 `DockAccessory.Limits(yaw: yawLimit, pitch: nil, roll: nil)`)。
- 播放内置动画:先 `setSystemTrackingEnabled(false)`,再 `accessory.animate(motion: .yes/.no/.wakeup/.kapow)`,用循环等待 `progress.isFinished || progress.isCancelled`,完成后恢复系统跟踪。
- 把 `animate(motion:)` 与 `setOrientation(_:duration:relative:)` 的调用频率控制在每秒不超过 2 次;应设置一条轨迹并观察其 `Progress`,避免紧密命令循环,否则可能抛 `.frameRateTooHigh`。
- iOS 18+ 用 `try accessory.trackingStates` 异步序列读取 ML 跟踪信号:遍历 `state.trackedSubjects`,处理 `.person`(`identifier`、`rect`、`speakingConfidence`、`lookingAtCameraConfidence`、`saliencyRank`)与 `.object`(`identifier`、`rect`、`saliencyRank`);`saliencyRank` 越小越显著。
- 用 `selectSubjects([id])` 按 UUID 锁定跟踪,传 `[]` 回到自动选择;选择优先级为 `speakingConfidence > 0.7` 作发言人、`lookingAtCameraConfidence > 0.7` 作注视者,否则回退到最小 `saliencyRank`;并用 `rect` 绘制主体叠加层。
- iOS 17.4+ 用 `#available(iOS 17.4, *)` 保护 `accessory.accessoryEvents` 异步序列,处理 `.cameraShutter`、`.cameraFlip`、`.cameraZoom(factor:)`、`.button(id:pressed:)`,第三方应用通过 AVFoundation 实现对应行为,并处理 `@unknown default`。
- iOS 18+ 用 `#available(iOS 18.0, *)` 保护 `accessory.batteryStates` 异步序列,按 `battery.name` 保存 `batteryLevel`、`chargeState`、`lowBattery`;多电池 dock 的 UI 要保留 `name` 以区分各电池。
- 对所有 DockKit 枚举的 switch 语句都补上 `@unknown default` 分支。
- 用运行时判断/条件隔离 DockKit 代码路径,保证 Simulator 构建不执行这些路径,并在没有配件可用时提供回退行为。
适用边界 · 注意事项
- 没有物理 DockKit 兼容配件、或在 Simulator 中运行时不要用(模拟器无法连接 dock 硬件)。
- 应用不使用 AVFoundation 相机 API 时不要用(DockKit 依赖相机管线分析帧实现系统跟踪)。
- 目标系统低于 iOS 17(配件事件需 17.4+、trackingStates 与 batteryStates 需 iOS 18+)时不要使用对应能力。