Agent skills for iOS, iPadOS, Swift, SwiftUI, and modern Apple framework development.
90
90%
Does it follow best practices?
Impact
—
Average score across 248 eval scenarios
Advisory
Suggest reviewing before use
Overflow reference for the core-motion skill. Contains advanced patterns that
exceed the main skill file's scope.
@Observable@Observableimport CoreMotion
import SwiftUI
@Observable
@MainActor
final class MotionService {
static let shared = MotionService()
private let manager = CMMotionManager()
var pitch: Double = 0
var roll: Double = 0
var yaw: Double = 0
var userAcceleration: CMAcceleration = CMAcceleration()
var isActive = false
func startDeviceMotion(interval: TimeInterval = 1.0 / 60.0) {
guard manager.isDeviceMotionAvailable, !isActive else { return }
manager.deviceMotionUpdateInterval = interval
manager.startDeviceMotionUpdates(
using: .xArbitraryZVertical,
to: .main
) { [weak self] motion, error in
guard let self, let motion else { return }
self.pitch = motion.attitude.pitch
self.roll = motion.attitude.roll
self.yaw = motion.attitude.yaw
self.userAcceleration = motion.userAcceleration
}
isActive = true
}
func stop() {
manager.stopDeviceMotionUpdates()
isActive = false
}
}struct TiltView: View {
@State private var motionService = MotionService.shared
var body: some View {
VStack {
Circle()
.fill(.blue)
.frame(width: 60, height: 60)
.offset(
x: motionService.roll * 100,
y: motionService.pitch * 100
)
Text("Roll: \(motionService.roll, format: .number.precision(.fractionLength(2)))")
Text("Pitch: \(motionService.pitch, format: .number.precision(.fractionLength(2)))")
}
.onAppear { motionService.startDeviceMotion() }
.onDisappear { motionService.stop() }
}
}struct LevelIndicator: View {
@State private var motionService = MotionService.shared
private var isLevel: Bool {
abs(motionService.pitch) < 0.05 && abs(motionService.roll) < 0.05
}
var body: some View {
ZStack {
Circle()
.stroke(isLevel ? .green : .gray, lineWidth: 3)
.frame(width: 200, height: 200)
Circle()
.fill(isLevel ? .green : .red)
.frame(width: 20, height: 20)
.offset(
x: motionService.roll * 100,
y: motionService.pitch * -100
)
}
.onAppear { motionService.startDeviceMotion(interval: 1.0 / 30.0) }
.onDisappear { motionService.stop() }
}
}CMBatchedSensorManager delivers batches of high-frequency accelerometer and
device-motion data for workout-style motion analysis, such as golf swings or bat
swings. The async update sequences are watchOS 10+ APIs; check availability and
authorization before starting updates.
import CoreMotion
@Observable
@MainActor
final class BatchedMotionService {
private let batchedManager = CMBatchedSensorManager()
private var updateTask: Task<Void, Never>?
var latestAcceleration: CMAcceleration?
func startBatchedAccelerometer() {
let authorization = CMBatchedSensorManager.authorizationStatus
guard CMBatchedSensorManager.isAccelerometerSupported,
authorization != .denied,
authorization != .restricted else { return }
updateTask = Task {
for await batch in batchedManager.accelerometerUpdates() {
guard !Task.isCancelled else { break }
// Process entire batch
for sample in batch {
// sample.acceleration, sample.timestamp
}
// Update UI with most recent
if let latest = batch.last {
latestAcceleration = latest.acceleration
}
}
}
}
func stop() {
updateTask?.cancel()
updateTask = nil
batchedManager.stopAccelerometerUpdates()
}
}let batchedManager = CMBatchedSensorManager()
// Start updates, then read the frequency the device reports.
batchedManager.startAccelerometerUpdates()
let reportedHz = batchedManager.accelerometerDataFrequencyaccelerometerDataFrequency and deviceMotionDataFrequency are read-only. Do
not assign them; use the reported values to size buffers, throttle UI updates, or
downsample processed results.
Track head motion using AirPods Pro / AirPods Max via CMHeadphoneMotionManager.
On iOS and macOS, include NSMotionUsageDescription. Use connection-status
updates when the app needs connect/disconnect events outside an active motion
session.
import CoreMotion
@Observable
@MainActor
final class HeadphoneMotionService: NSObject {
private let headphoneManager = CMHeadphoneMotionManager()
var isConnected = false
var headPitch: Double = 0
var headYaw: Double = 0
func start() {
guard headphoneManager.isDeviceMotionAvailable else { return }
headphoneManager.delegate = self
headphoneManager.startConnectionStatusUpdates()
headphoneManager.startDeviceMotionUpdates(to: .main) { [weak self] motion, error in
guard let self, let motion else { return }
self.headPitch = motion.attitude.pitch
self.headYaw = motion.attitude.yaw
}
}
func stop() {
headphoneManager.stopDeviceMotionUpdates()
headphoneManager.stopConnectionStatusUpdates()
}
}
extension HeadphoneMotionService: CMHeadphoneMotionManagerDelegate {
nonisolated func headphoneMotionManagerDidConnect(
_ manager: CMHeadphoneMotionManager
) {
Task { @MainActor in isConnected = true }
}
nonisolated func headphoneMotionManagerDidDisconnect(
_ manager: CMHeadphoneMotionManager
) {
Task { @MainActor in isConnected = false }
}
}import CoreMotion
import SwiftUI
@Observable
@MainActor
final class PedometerService {
private let pedometer = CMPedometer()
var todaySteps: Int = 0
var todayDistance: Double = 0
var floorsAscended: Int = 0
func fetchToday() {
guard CMPedometer.isStepCountingAvailable() else { return }
let startOfDay = Calendar.current.startOfDay(for: Date())
pedometer.queryPedometerData(from: startOfDay, to: Date()) { [weak self] data, error in
guard let self, let data else { return }
Task { @MainActor in
self.todaySteps = data.numberOfSteps.intValue
self.todayDistance = data.distance?.doubleValue ?? 0
self.floorsAscended = data.floorsAscended?.intValue ?? 0
}
}
}
func startLiveUpdates() {
guard CMPedometer.isStepCountingAvailable() else { return }
let startOfDay = Calendar.current.startOfDay(for: Date())
pedometer.startUpdates(from: startOfDay) { [weak self] data, error in
guard let self, let data else { return }
Task { @MainActor in
self.todaySteps = data.numberOfSteps.intValue
self.todayDistance = data.distance?.doubleValue ?? 0
self.floorsAscended = data.floorsAscended?.intValue ?? 0
}
}
}
func stopLiveUpdates() {
pedometer.stopUpdates()
}
}struct StepDashboard: View {
@State private var pedometerService = PedometerService()
var body: some View {
List {
Section("Today") {
LabeledContent("Steps") {
Text("\(pedometerService.todaySteps)")
}
LabeledContent("Distance") {
Text(
Measurement(value: pedometerService.todayDistance, unit: UnitLength.meters),
format: .measurement(width: .abbreviated)
)
}
if CMPedometer.isFloorCountingAvailable() {
LabeledContent("Floors Climbed") {
Text("\(pedometerService.floorsAscended)")
}
}
}
}
.onAppear { pedometerService.startLiveUpdates() }
.onDisappear { pedometerService.stopLiveUpdates() }
}
}Switch between driving and walking modes automatically:
import CoreMotion
@Observable
@MainActor
final class NavigationModeService {
private let activityManager = CMMotionActivityManager()
enum Mode: String {
case walking, driving, cycling, unknown
}
var currentMode: Mode = .unknown
func startMonitoring() {
guard CMMotionActivityManager.isActivityAvailable() else { return }
activityManager.startActivityUpdates(to: .main) { [weak self] activity in
guard let self, let activity,
activity.confidence != .low else { return }
Task { @MainActor in
if activity.automotive {
self.currentMode = .driving
} else if activity.cycling {
self.currentMode = .cycling
} else if activity.walking || activity.running {
self.currentMode = .walking
} else if activity.stationary {
// Keep previous mode when stationary (e.g., at a stoplight)
}
}
}
}
func stopMonitoring() {
activityManager.stopActivityUpdates()
}
}Track water depth and temperature for dive apps on supported Apple Watch
hardware. Use waterSubmersionAvailable rather than hard-coding model checks:
Apple Watch Ultra supports submersion data, and Apple Watch Series 10 supports
the Shallow Depth and Pressure capability.
Setup checklist:
NSMotionUsageDescription.WKBackgroundModes with underwater-depth so the app can remain
frontmost and eligible for dive autolaunch.CMWaterSubmersionManager.import CoreMotion
@Observable
@MainActor
final class DiveService: NSObject {
private var submersionManager: CMWaterSubmersionManager?
var isSubmerged = false
var currentDepth: Double?
var waterTemperature: Double?
func start() {
guard CMWaterSubmersionManager.waterSubmersionAvailable else { return }
let manager = CMWaterSubmersionManager()
manager.delegate = self
submersionManager = manager
}
}
extension DiveService: CMWaterSubmersionManagerDelegate {
nonisolated func manager(
_ manager: CMWaterSubmersionManager,
didUpdate event: CMWaterSubmersionEvent
) {
Task { @MainActor in
isSubmerged = event.state == .submerged
}
}
nonisolated func manager(
_ manager: CMWaterSubmersionManager,
didUpdate measurement: CMWaterSubmersionMeasurement
) {
Task { @MainActor in
currentDepth = measurement.depth?.value
}
}
nonisolated func manager(
_ manager: CMWaterSubmersionManager,
didUpdate temperature: CMWaterTemperature
) {
Task { @MainActor in
waterTemperature = temperature.temperature.value
}
}
nonisolated func manager(
_ manager: CMWaterSubmersionManager,
errorOccurred error: any Error
) {
print("Submersion error: \(error)")
}
}Important: CMWaterSubmersionManager requires the
Shallow Depth and Pressure capability or the full Submerged Depth and Pressure
entitlement. If the app lacks the entitlement, the delegate receives
CMError.notEntitled and no submersion data.
.tessl-plugin
skills
accessorysetupkit
references
activitykit
references
adattributionkit
references
alarmkit
references
app-clips
app-intents
references
app-store-optimization
app-store-review
apple-on-device-ai
appmigrationkit
references
audioaccessorykit
references
authentication
references
avkit
references
background-processing
references
browserenginekit
references
callkit
references
carplay
references
cloudkit
references
contacts-framework
references
core-bluetooth
references
core-data
core-motion
references
core-nfc
references
coreml
references
cryptokit
references
cryptotokenkit
references
debugging-instruments
device-integrity
references
dockkit
references
energykit
references
eventkit
references
financekit
references
focus-engine
gamekit
references
healthkit
references
homekit
references
ios-accessibility
ios-localization
ios-networking
ios-simulator
references
mapkit
metrickit
references
musickit
references
natural-language
references
paperkit
references
passkit
references
pdfkit
references
pencilkit
references
permissionkit
references
photokit
push-notifications
realitykit
references
relevancekit
references
scenekit
references
sensorkit
references
speech-recognition
references
spritekit
references
storekit
swift-api-design-guidelines
swift-architecture
swift-charts
references
swift-codable
swift-concurrency
swift-formatstyle
swift-language
swift-security
references
swift-testing
swiftdata
swiftlint
swiftui-animation
swiftui-gestures
references
swiftui-layout-components
swiftui-liquid-glass
references
swiftui-patterns
swiftui-performance
swiftui-uikit-interop
swiftui-webkit
tabletopkit
references
tipkit
references
vision-framework
weatherkit
references
widgetkit
references