Control motorized camera docks and enable intelligent subject tracking using DockKit. Use when discovering DockKit-compatible accessories, implementing camera subject tracking for faces or bodies, controlling dock motors for pan and tilt, configuring framing behavior, setting regions of interest, or building video apps with automatic camera tracking.
91%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Framework for integrating with motorized camera stands and gimbals that physically track subjects by rotating the iPhone. DockKit handles motor control, subject detection, and framing so camera apps get 360-degree pan and 90-degree tilt tracking with no additional code. Apps can override system tracking to supply custom observations, control motors directly, or adjust framing. iOS 17+, Swift 6.4.
// WRONG -- system tracking fights manual commands
try await accessory.setAngularVelocity(velocity)
// CORRECT -- disable system tracking first
try await DockAccessoryManager.shared.setSystemTrackingEnabled(false)
try await accessory.setAngularVelocity(velocity)// WRONG -- state may have reset after backgrounding
func applicationDidBecomeActive() {
// Assume custom tracking is still active
}
// CORRECT -- re-set tracking state on foreground
func applicationDidBecomeActive() {
Task {
try await DockAccessoryManager.shared.setSystemTrackingEnabled(false)
}
}// WRONG -- calling once per second is too slow
try await accessory.track(observations, cameraInformation: cameraInfo)
// (called at 1 fps)
// CORRECT -- call at 10-30 fps
// Hook into AVCaptureVideoDataOutputSampleBufferDelegate for per-frame callsDockKit can throw .frameRateTooHigh if animate(motion:) or
setOrientation(_:duration:relative:) is called more than twice per second.
Set a trajectory, observe its Progress, and avoid tight command loops.
// WRONG -- tracking stays disabled after animation
try await DockAccessoryManager.shared.setSystemTrackingEnabled(false)
let progress = try await accessory.animate(motion: .kapow)
// CORRECT -- restore tracking when animation completes
try await DockAccessoryManager.shared.setSystemTrackingEnabled(false)
let progress = try await accessory.animate(motion: .kapow)
while !progress.isFinished && !progress.isCancelled {
try await Task.sleep(for: .milliseconds(100))
}
try await DockAccessoryManager.shared.setSystemTrackingEnabled(true)DockKit requires a physical DockKit-compatible accessory. Guard initialization and provide fallback behavior when no accessory is available.
import DockKit present where neededaccessoryStateChanges to detect dock/undock events.docked and .undocked statesanimate and setOrientation commands limited to 2 calls per secondrect uses normalized coordinates (lower-left origin)AVCaptureDevice and current sample buffer.humanFace, .humanBody, and .object@unknown default handled in all switch statements over DockKit enumsaccessoryEvents guarded with #available(iOS 17.4, *)trackingStates and batteryStates guarded with #available(iOS 18.0, *)BatteryState.name for multi-battery docksthienqo/ios-skills
6bf8b62
Canonical home
since May 23, 2026
Also appears in
on Oct 29, 2026
since May 22, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.