{"id":"5833d5fa-7c91-4935-b172-dbb0a3e92afb","shortId":"gvZxV2","kind":"skill","title":"Core Motion","tagline":"Swift Ios Skills skill by Dpearson2699","description":"# CoreMotion\n\nRead device sensor data -- accelerometer, gyroscope, magnetometer, pedometer, and\nactivity recognition -- on iOS and watchOS. CoreMotion fuses raw sensor inputs into\nprocessed device-motion data and provides pedometer/activity APIs for fitness and\nnavigation use cases. Targets Swift 6.3 / iOS 26+.\n\n## Contents\n\n- [Setup](#setup)\n- [CMMotionManager: Sensor Data](#cmmotionmanager-sensor-data)\n- [Processed Device Motion](#processed-device-motion)\n- [CMPedometer: Step and Distance Data](#cmpedometer-step-and-distance-data)\n- [CMMotionActivityManager: Activity Recognition](#cmmotionactivitymanager-activity-recognition)\n- [CMAltimeter: Altitude Data](#cmaltimeter-altitude-data)\n- [Update Intervals and Battery](#update-intervals-and-battery)\n- [Common Mistakes](#common-mistakes)\n- [Review Checklist](#review-checklist)\n- [References](#references)\n\n## Setup\n\n### Info.plist\n\nAdd `NSMotionUsageDescription` to Info.plist with a user-facing string explaining\nwhy your app needs motion data. Without this key, the app crashes on first access.\n\n```xml\n<key>NSMotionUsageDescription</key>\n<string>This app uses motion data to track your activity.</string>\n```\n\n### Authorization\n\nCoreMotion uses `CMAuthorizationStatus` for pedometer and activity APIs. Sensor\nAPIs (accelerometer, gyro) do not require explicit authorization but do require\nthe usage description key.\n\n```swift\nimport CoreMotion\n\nlet status = CMMotionActivityManager.authorizationStatus()\nswitch status {\ncase .notDetermined:\n    // Will prompt on first use\n    break\ncase .authorized:\n    break\ncase .restricted, .denied:\n    // Direct user to Settings\n    break\n@unknown default:\n    break\n}\n```\n\n## CMMotionManager: Sensor Data\n\nCreate exactly **one** `CMMotionManager` per app. Multiple instances degrade\nsensor update rates.\n\n```swift\nimport CoreMotion\n\nlet motionManager = CMMotionManager()\n```\n\n### Accelerometer Updates\n\n```swift\nguard motionManager.isAccelerometerAvailable else { return }\n\nmotionManager.accelerometerUpdateInterval = 1.0 / 60.0  // 60 Hz\n\nmotionManager.startAccelerometerUpdates(to: .main) { data, error in\n    guard let acceleration = data?.acceleration else { return }\n    print(\"x: \\(acceleration.x), y: \\(acceleration.y), z: \\(acceleration.z)\")\n}\n\n// When done:\nmotionManager.stopAccelerometerUpdates()\n```\n\n### Gyroscope Updates\n\n```swift\nguard motionManager.isGyroAvailable else { return }\n\nmotionManager.gyroUpdateInterval = 1.0 / 60.0\n\nmotionManager.startGyroUpdates(to: .main) { data, error in\n    guard let rotationRate = data?.rotationRate else { return }\n    print(\"x: \\(rotationRate.x), y: \\(rotationRate.y), z: \\(rotationRate.z)\")\n}\n\nmotionManager.stopGyroUpdates()\n```\n\n### Polling Pattern (Games)\n\nFor games, start updates without a handler and poll the latest sample each frame:\n\n```swift\nmotionManager.startAccelerometerUpdates()\n\n// In your game loop / display link:\nif let data = motionManager.accelerometerData {\n    let tilt = data.acceleration.x\n    // Move player based on tilt\n}\n```\n\n## Processed Device Motion\n\nDevice motion fuses accelerometer, gyroscope, and magnetometer into a single\n`CMDeviceMotion` object with attitude, user acceleration (gravity removed),\nrotation rate, and calibrated magnetic field.\n\n```swift\nguard motionManager.isDeviceMotionAvailable else { return }\n\nmotionManager.deviceMotionUpdateInterval = 1.0 / 60.0\n\nmotionManager.startDeviceMotionUpdates(\n    using: .xArbitraryZVertical,\n    to: .main\n) { motion, error in\n    guard let motion else { return }\n\n    let attitude = motion.attitude       // roll, pitch, yaw\n    let userAccel = motion.userAcceleration\n    let gravity = motion.gravity\n    let heading = motion.heading         // 0-360 degrees (requires magnetometer)\n\n    print(\"Pitch: \\(attitude.pitch), Roll: \\(attitude.roll)\")\n}\n\nmotionManager.stopDeviceMotionUpdates()\n```\n\n### Attitude Reference Frames\n\n| Frame | Use Case |\n|---|---|\n| `.xArbitraryZVertical` | Default. Z is vertical, X arbitrary at start. Most games. |\n| `.xArbitraryCorrectedZVertical` | Same as above, corrected for gyro drift over time. |\n| `.xMagneticNorthZVertical` | X points to magnetic north. Requires magnetometer. |\n| `.xTrueNorthZVertical` | X points to true north. Requires magnetometer + location. |\n\nCheck available frames before use:\n\n```swift\nlet available = CMMotionManager.availableAttitudeReferenceFrames()\nif available.contains(.xTrueNorthZVertical) {\n    // Safe to use true north\n}\n```\n\n## CMPedometer: Step and Distance Data\n\n`CMPedometer` provides step counts, distance, pace, cadence, and floor counts.\n\n```swift\nlet pedometer = CMPedometer()\n\nguard CMPedometer.isStepCountingAvailable() else { return }\n\n// Historical query\npedometer.queryPedometerData(\n    from: Calendar.current.startOfDay(for: Date()),\n    to: Date()\n) { data, error in\n    guard let data else { return }\n    print(\"Steps today: \\(data.numberOfSteps)\")\n    print(\"Distance: \\(data.distance?.doubleValue ?? 0) meters\")\n    print(\"Floors up: \\(data.floorsAscended?.intValue ?? 0)\")\n}\n\n// Live updates\npedometer.startUpdates(from: Date()) { data, error in\n    guard let data else { return }\n    print(\"Steps: \\(data.numberOfSteps)\")\n}\n\n// Stop when done\npedometer.stopUpdates()\n```\n\n### Availability Checks\n\n| Method | What It Checks |\n|---|---|\n| `isStepCountingAvailable()` | Step counter hardware |\n| `isDistanceAvailable()` | Distance estimation |\n| `isFloorCountingAvailable()` | Barometric altimeter for floors |\n| `isPaceAvailable()` | Pace data |\n| `isCadenceAvailable()` | Cadence data |\n\n## CMMotionActivityManager: Activity Recognition\n\nDetects whether the user is stationary, walking, running, cycling, or in a vehicle.\n\n```swift\nlet activityManager = CMMotionActivityManager()\n\nguard CMMotionActivityManager.isActivityAvailable() else { return }\n\n// Live activity updates\nactivityManager.startActivityUpdates(to: .main) { activity in\n    guard let activity else { return }\n\n    if activity.walking {\n        print(\"Walking (confidence: \\(activity.confidence.rawValue))\")\n    } else if activity.running {\n        print(\"Running\")\n    } else if activity.automotive {\n        print(\"In vehicle\")\n    } else if activity.cycling {\n        print(\"Cycling\")\n    } else if activity.stationary {\n        print(\"Stationary\")\n    }\n}\n\nactivityManager.stopActivityUpdates()\n```\n\n### Historical Activity Query\n\n```swift\nlet yesterday = Calendar.current.date(byAdding: .day, value: -1, to: Date())!\n\nactivityManager.queryActivityStarting(\n    from: yesterday,\n    to: Date(),\n    to: .main\n) { activities, error in\n    guard let activities else { return }\n    for activity in activities {\n        print(\"\\(activity.startDate): walking=\\(activity.walking)\")\n    }\n}\n```\n\n## CMAltimeter: Altitude Data\n\n```swift\nlet altimeter = CMAltimeter()\n\nguard CMAltimeter.isRelativeAltitudeAvailable() else { return }\n\naltimeter.startRelativeAltitudeUpdates(to: .main) { data, error in\n    guard let data else { return }\n    print(\"Relative altitude: \\(data.relativeAltitude) meters\")\n    print(\"Pressure: \\(data.pressure) kPa\")\n}\n\naltimeter.stopRelativeAltitudeUpdates()\n```\n\nFor absolute altitude (GPS-based):\n\n```swift\nguard CMAltimeter.isAbsoluteAltitudeAvailable() else { return }\n\naltimeter.startAbsoluteAltitudeUpdates(to: .main) { data, error in\n    guard let data else { return }\n    print(\"Altitude: \\(data.altitude)m, accuracy: \\(data.accuracy)m\")\n}\n\naltimeter.stopAbsoluteAltitudeUpdates()\n```\n\n## Update Intervals and Battery\n\n| Interval | Hz | Use Case | Battery Impact |\n|---|---|---|---|\n| `1.0 / 10.0` | 10 | UI orientation | Low |\n| `1.0 / 30.0` | 30 | Casual games | Moderate |\n| `1.0 / 60.0` | 60 | Action games | High |\n| `1.0 / 100.0` | 100 | Max rate (iPhone) | Very High |\n\nUse the lowest frequency that meets your needs. `CMMotionManager` caps at 100 Hz\nper sample. For higher frequencies, use `CMBatchedSensorManager` on watchOS/iOS 17+.\n\n## Common Mistakes\n\n### DON'T: Create multiple CMMotionManager instances\n\n```swift\n// WRONG -- degrades update rates for all instances\nclass ViewA { let motion = CMMotionManager() }\nclass ViewB { let motion = CMMotionManager() }\n\n// CORRECT -- single instance, shared across the app\n@Observable\nfinal class MotionService {\n    static let shared = MotionService()\n    let manager = CMMotionManager()\n}\n```\n\n### DON'T: Skip sensor availability checks\n\n```swift\n// WRONG -- crashes on devices without gyroscope\nmotionManager.startGyroUpdates(to: .main) { data, _ in }\n\n// CORRECT -- check first\nguard motionManager.isGyroAvailable else {\n    showUnsupportedMessage()\n    return\n}\nmotionManager.startGyroUpdates(to: .main) { data, _ in }\n```\n\n### DON'T: Forget to stop updates\n\n```swift\n// WRONG -- updates keep running, draining battery\nclass MotionVC: UIViewController {\n    override func viewDidAppear(_ animated: Bool) {\n        super.viewDidAppear(animated)\n        motionManager.startAccelerometerUpdates(to: .main) { _, _ in }\n    }\n    // Missing viewDidDisappear stop!\n}\n\n// CORRECT -- stop in the counterpart lifecycle method\noverride func viewDidDisappear(_ animated: Bool) {\n    super.viewDidDisappear(animated)\n    motionManager.stopAccelerometerUpdates()\n}\n```\n\n### DON'T: Use unnecessarily high update rates\n\n```swift\n// WRONG -- 100 Hz for a compass display\nmotionManager.deviceMotionUpdateInterval = 1.0 / 100.0\n\n// CORRECT -- 10 Hz is more than enough for a compass\nmotionManager.deviceMotionUpdateInterval = 1.0 / 10.0\n```\n\n### DON'T: Assume all CMMotionActivity properties are mutually exclusive\n\n```swift\n// WRONG -- checking only one property\nif activity.walking { handleWalking() }\n\n// CORRECT -- multiple can be true simultaneously; check confidence\nif activity.walking && activity.confidence == .high {\n    handleWalking()\n} else if activity.automotive && activity.confidence != .low {\n    handleDriving()\n}\n```\n\n## Review Checklist\n\n- [ ] `NSMotionUsageDescription` present in Info.plist with a clear explanation\n- [ ] Single `CMMotionManager` instance shared across the app\n- [ ] Sensor availability checked before starting updates (`isAccelerometerAvailable`, etc.)\n- [ ] Authorization status checked before pedometer/activity APIs\n- [ ] Update interval set to the lowest acceptable frequency\n- [ ] All `start*Updates` calls have matching `stop*Updates` in lifecycle counterparts\n- [ ] Handlers dispatched to appropriate queues (not blocking main for heavy processing)\n- [ ] `CMMotionActivity.confidence` checked before acting on activity type\n- [ ] Error parameters checked in update handlers\n- [ ] Attitude reference frame chosen based on actual need (not defaulting to true north unnecessarily)\n\n## References\n\n- Extended patterns (SwiftUI integration, batched sensor manager, headphone motion): [references/motion-patterns.md](references/motion-patterns.md)\n- [CoreMotion framework](https://sosumi.ai/documentation/coremotion)\n- [CMMotionManager](https://sosumi.ai/documentation/coremotion/cmmotionmanager)\n- [CMPedometer](https://sosumi.ai/documentation/coremotion/cmpedometer)\n- [CMMotionActivityManager](https://sosumi.ai/documentation/coremotion/cmmotionactivitymanager)\n- [CMDeviceMotion](https://sosumi.ai/documentation/coremotion/cmdevicemotion)\n- [CMAltimeter](https://sosumi.ai/documentation/coremotion/cmaltimeter)\n- [CMBatchedSensorManager](https://sosumi.ai/documentation/coremotion/cmbatchedsensormanager)\n- [Getting processed device-motion data](https://sosumi.ai/documentation/coremotion/getting-processed-device-motion-data)","tags":["core","motion","swift","ios","skills","dpearson2699"],"capabilities":["skill","source-dpearson2699","category-swift-ios-skills"],"categories":["swift-ios-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/dpearson2699/swift-ios-skills/core-motion","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"install_from":"skills.sh"}},"qualityScore":"0.300","qualityRationale":"deterministic score 0.30 from registry signals: · indexed on skills.sh · published under dpearson2699/swift-ios-skills","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T03:40:33.737Z","embedding":null,"createdAt":"2026-04-18T20:34:35.814Z","updatedAt":"2026-04-22T03:40:33.737Z","lastSeenAt":"2026-04-22T03:40:33.737Z","tsv":"'-1':643 '-360':397 '/documentation/coremotion)':1082 '/documentation/coremotion/cmaltimeter)':1102 '/documentation/coremotion/cmbatchedsensormanager)':1106 '/documentation/coremotion/cmdevicemotion)':1098 '/documentation/coremotion/cmmotionactivitymanager)':1094 '/documentation/coremotion/cmmotionmanager)':1086 '/documentation/coremotion/cmpedometer)':1090 '/documentation/coremotion/getting-processed-device-motion-data)':1115 '0':396,516,523 '1.0':237,272,366,741,747,753,759,926,939 '10':743,929 '10.0':742,940 '100':761,778,919 '100.0':760,927 '17':789 '26':50 '30':749 '30.0':748 '6.3':48 '60':239,755 '60.0':238,273,367,754 'absolut':702 'acceler':249,251,351 'acceleration.x':256 'acceleration.y':258 'acceleration.z':260 'acceleromet':14,164,229,339 'accept':1015 'access':141 'accuraci':727 'across':820,992 'act':1042 'action':756 'activ':19,80,84,152,160,569,593,598,602,634,653,658,662,664,1044 'activity.automotive':618,974 'activity.confidence':969,975 'activity.confidence.rawvalue':610 'activity.cycling':624 'activity.running':613 'activity.startdate':666 'activity.stationary':629 'activity.walking':606,668,957,968 'activitymanag':586 'activitymanager.queryactivitystarting':646 'activitymanager.startactivityupdates':595 'activitymanager.stopactivityupdates':632 'actual':1058 'add':116 'altimet':559,674 'altimeter.startabsolutealtitudeupdates':712 'altimeter.startrelativealtitudeupdates':680 'altimeter.stopabsolutealtitudeupdates':730 'altimeter.stoprelativealtitudeupdates':700 'altitud':87,91,670,693,703,724 'anim':884,887,905,908 'api':39,161,163,1008 'app':129,137,145,216,822,994 'appropri':1031 'arbitrari':419 'assum':943 'attitud':349,382,407,1052 'attitude.pitch':403 'attitude.roll':405 'author':153,170,195,1003 'avail':452,458,544,838,996 'available.contains':461 'barometr':558 'base':330,706,1056 'batch':1071 'batteri':96,101,734,739,877 'block':1034 'bool':885,906 'break':193,196,204,207 'byad':640 'cadenc':479,566 'calendar.current.date':639 'calendar.current.startofday':495 'calibr':357 'call':1020 'cap':776 'case':45,186,194,197,412,738 'casual':750 'category-swift-ios-skills' 'check':451,545,549,839,853,952,965,997,1005,1040,1048 'checklist':108,111,979 'chosen':1055 'class':806,811,825,878 'clear':986 'cmaltimet':86,90,669,675,1099 'cmaltimeter-altitude-data':89 'cmaltimeter.isabsolutealtitudeavailable':709 'cmaltimeter.isrelativealtitudeavailable':677 'cmauthorizationstatus':156 'cmbatchedsensormanag':786,1103 'cmdevicemot':346,1095 'cmmotionact':945 'cmmotionactivity.confidence':1039 'cmmotionactivitymanag':79,83,568,587,1091 'cmmotionactivitymanager-activity-recognit':82 'cmmotionactivitymanager.authorizationstatus':183 'cmmotionactivitymanager.isactivityavailable':589 'cmmotionmanag':54,58,208,214,228,775,796,810,815,833,989,1083 'cmmotionmanager-sensor-data':57 'cmmotionmanager.availableattitudereferenceframes':459 'cmpedomet':68,74,468,473,486,1087 'cmpedometer-step-and-distance-data':73 'cmpedometer.isstepcountingavailable':488 'common':102,105,790 'common-mistak':104 'compass':923,937 'confid':609,966 'content':51 'core':1 'coremot':9,25,154,180,225,1078 'correct':428,816,852,895,928,959 'count':476,482 'counter':552 'counterpart':899,1027 'crash':138,842 'creat':211,794 'cycl':579,626 'data':13,35,56,60,72,78,88,92,132,148,210,244,250,277,283,322,472,500,505,529,534,564,567,671,683,688,715,720,850,863,1112 'data.acceleration':326 'data.accuracy':728 'data.altitude':725 'data.distance':514 'data.floorsascended':521 'data.numberofsteps':511,539 'data.pressure':698 'data.relativealtitude':694 'date':497,499,528,645,650 'day':641 'default':206,414,1061 'degrad':219,800 'degre':398 'deni':199 'descript':176 'detect':571 'devic':11,33,62,66,334,336,844,1110 'device-mot':32,1109 'direct':200 'dispatch':1029 'display':318,924 'distanc':71,77,471,477,513,555 'done':262,542 'doublevalu':515 'dpearson2699':8 'drain':876 'drift':431 'els':234,252,269,285,363,379,489,506,535,590,603,611,616,622,627,659,678,689,710,721,857,972 'enough':934 'error':245,278,374,501,530,654,684,716,1046 'estim':556 'etc':1002 'exact':212 'exclus':949 'explain':126 'explan':987 'explicit':169 'extend':1067 'face':124 'field':359 'final':824 'first':140,191,854 'fit':41 'floor':481,519,561 'forget':867 'frame':311,409,410,453,1054 'framework':1079 'frequenc':770,784,1016 'func':882,903 'fuse':26,338 'game':297,299,316,423,751,757 'get':1107 'gps':705 'gps-base':704 'graviti':352,391 'guard':232,247,267,280,361,376,487,503,532,588,600,656,676,686,708,718,855 'gyro':165,430 'gyroscop':15,264,340,846 'handledriv':977 'handler':304,1028,1051 'handlewalk':958,971 'hardwar':553 'head':394 'headphon':1074 'heavi':1037 'high':758,766,914,970 'higher':783 'histor':491,633 'hz':240,736,779,920,930 'impact':740 'import':179,224 'info.plist':115,119,983 'input':29 'instanc':218,797,805,818,990 'integr':1070 'interv':94,99,732,735,1010 'intvalu':522 'io':4,22,49 'iphon':764 'isaccelerometeravail':1001 'iscadenceavail':565 'isdistanceavail':554 'isfloorcountingavail':557 'ispaceavail':562 'isstepcountingavail':550 'keep':874 'key':135,177 'kpa':699 'latest':308 'let':181,226,248,281,321,324,377,381,387,390,393,457,484,504,533,585,601,637,657,673,687,719,808,813,828,831 'lifecycl':900,1026 'link':319 'live':524,592 'locat':450 'loop':317 'low':746,976 'lowest':769,1014 'm':726,729 'magnet':358,438 'magnetomet':16,342,400,441,449 'main':243,276,372,597,652,682,714,849,862,890,1035 'manag':832,1073 'match':1022 'max':762 'meet':772 'meter':517,695 'method':546,901 'miss':892 'mistak':103,106,791 'moder':752 'motion':2,34,63,67,131,147,335,337,373,378,809,814,1075,1111 'motion.attitude':383 'motion.gravity':392 'motion.heading':395 'motion.useracceleration':389 'motionmanag':227 'motionmanager.accelerometerdata':323 'motionmanager.accelerometerupdateinterval':236 'motionmanager.devicemotionupdateinterval':365,925,938 'motionmanager.gyroupdateinterval':271 'motionmanager.isaccelerometeravailable':233 'motionmanager.isdevicemotionavailable':362 'motionmanager.isgyroavailable':268,856 'motionmanager.startaccelerometerupdates':241,313,888 'motionmanager.startdevicemotionupdates':368 'motionmanager.startgyroupdates':274,847,860 'motionmanager.stopaccelerometerupdates':263,909 'motionmanager.stopdevicemotionupdates':406 'motionmanager.stopgyroupdates':294 'motionservic':826,830 'motionvc':879 'move':328 'multipl':217,795,960 'mutual':948 'navig':43 'need':130,774,1059 'north':439,447,467,1064 'notdetermin':187 'nsmotionusagedescript':117,143,980 'object':347 'observ':823 'one':213,954 'orient':745 'overrid':881,902 'pace':478,563 'paramet':1047 'pattern':296,1068 'pedomet':17,158,485 'pedometer.querypedometerdata':493 'pedometer.startupdates':526 'pedometer.stopupdates':543 'pedometer/activity':38,1007 'per':215,780 'pitch':385,402 'player':329 'point':436,444 'poll':295,306 'present':981 'pressur':697 'print':254,287,401,508,512,518,537,607,614,619,625,630,665,691,696,723 'process':31,61,65,333,1038,1108 'processed-device-mot':64 'prompt':189 'properti':946,955 'provid':37,474 'queri':492,635 'queue':1032 'rate':222,355,763,802,916 'raw':27 'read':10 'recognit':20,81,85,570 'refer':112,113,408,1053,1066 'references/motion-patterns.md':1076,1077 'relat':692 'remov':353 'requir':168,173,399,440,448 'restrict':198 'return':235,253,270,286,364,380,490,507,536,591,604,660,679,690,711,722,859 'review':107,110,978 'review-checklist':109 'roll':384,404 'rotat':354 'rotationr':282,284 'rotationrate.x':289 'rotationrate.y':291 'rotationrate.z':293 'run':578,615,875 'safe':463 'sampl':309,781 'sensor':12,28,55,59,162,209,220,837,995,1072 'set':203,1011 'setup':52,53,114 'share':819,829,991 'showunsupportedmessag':858 'simultan':964 'singl':345,817,988 'skill':5,6 'skip':836 'sosumi.ai':1081,1085,1089,1093,1097,1101,1105,1114 'sosumi.ai/documentation/coremotion)':1080 'sosumi.ai/documentation/coremotion/cmaltimeter)':1100 'sosumi.ai/documentation/coremotion/cmbatchedsensormanager)':1104 'sosumi.ai/documentation/coremotion/cmdevicemotion)':1096 'sosumi.ai/documentation/coremotion/cmmotionactivitymanager)':1092 'sosumi.ai/documentation/coremotion/cmmotionmanager)':1084 'sosumi.ai/documentation/coremotion/cmpedometer)':1088 'sosumi.ai/documentation/coremotion/getting-processed-device-motion-data)':1113 'source-dpearson2699' 'start':300,421,999,1018 'static':827 'stationari':576,631 'status':182,185,1004 'step':69,75,469,475,509,538,551 'stop':540,869,894,896,1023 'string':125 'super.viewdidappear':886 'super.viewdiddisappear':907 'swift':3,47,178,223,231,266,312,360,456,483,584,636,672,707,798,840,871,917,950 'swiftui':1069 'switch':184 'target':46 'tilt':325,332 'time':433 'today':510 'track':150 'true':446,466,963,1063 'type':1045 'ui':744 'uiviewcontrol':880 'unknown':205 'unnecessarili':913,1065 'updat':93,98,221,230,265,301,525,594,731,801,870,873,915,1000,1009,1019,1024,1050 'update-intervals-and-batteri':97 'usag':175 'use':44,146,155,192,369,411,455,465,737,767,785,912 'user':123,201,350,574 'user-fac':122 'useraccel':388 'valu':642 'vehicl':583,621 'vertic':417 'viewa':807 'viewb':812 'viewdidappear':883 'viewdiddisappear':893,904 'walk':577,608,667 'watcho':24 'watchos/ios':788 'whether':572 'without':133,302,845 'wrong':799,841,872,918,951 'x':255,288,327,418,435,443 'xarbitrarycorrectedzvert':424 'xarbitraryzvert':370,413 'xmagneticnorthzvert':434 'xml':142 'xtruenorthzvert':442,462 'y':257,290 'yaw':386 'yesterday':638,648 'z':259,292,415","prices":[{"id":"a054cf58-7957-49fa-a90b-fc0d35123806","listingId":"5833d5fa-7c91-4935-b172-dbb0a3e92afb","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"dpearson2699","category":"swift-ios-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T20:34:35.814Z"}],"sources":[{"listingId":"5833d5fa-7c91-4935-b172-dbb0a3e92afb","source":"github","sourceId":"dpearson2699/swift-ios-skills/core-motion","sourceUrl":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/core-motion","isPrimary":false,"firstSeenAt":"2026-04-18T22:00:52.313Z","lastSeenAt":"2026-04-22T00:53:42.274Z"},{"listingId":"5833d5fa-7c91-4935-b172-dbb0a3e92afb","source":"skills_sh","sourceId":"dpearson2699/swift-ios-skills/core-motion","sourceUrl":"https://skills.sh/dpearson2699/swift-ios-skills/core-motion","isPrimary":true,"firstSeenAt":"2026-04-18T20:34:35.814Z","lastSeenAt":"2026-04-22T03:40:33.737Z"}],"details":{"listingId":"5833d5fa-7c91-4935-b172-dbb0a3e92afb","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"dpearson2699","slug":"core-motion","source":"skills_sh","category":"swift-ios-skills","skills_sh_url":"https://skills.sh/dpearson2699/swift-ios-skills/core-motion"},"updatedAt":"2026-04-22T03:40:33.737Z"}}