.isDeviceMotionAvailable returns true, but data from .deviceMotion is always nil

Hello everyone.

I'm trying to work with Core Motion, getting readings from my Apple Watch (Series 4), but am getting inconsistent behaviour.

If I run the code from Apples Core Motion documentation (see Listing 1), I don't get any readings.

The code I run, which works fine on iPhone, but not on Apple Watch, is:
Code Block
func startDeviceMotion() {
if motion.isDeviceMotionAvailable {
self.motion.deviceMotionUpdateInterval = 1.0 / 60.0
self.motion.showsDeviceMovementDisplay = true
self.motion.startDeviceMotionUpdates(using: .xMagneticNorthZVertical)
self.timer = Timer(fire: Date(), interval: (1.0 / 60.0), repeats: true, block: { (timer) in
if let data = self.motion.deviceMotion {
let x = data.attitude.pitch
let y = data.attitude.roll
let z = data.attitude.yaw
}
})
RunLoop.current.add(self.timer!, forMode: RunLoop.Mode.default)
}
}

The problem is that although .isDeviceMotionAvailable returns true and runs the if statement correctly, the returned data from self.motion.deviceMotion only gives me nil's.

I.e. DeviceMotion is available but still returns nil.

What I have tried so far without luck, is:
  • Adding various Accelerometer, Gyroscope, Location, and Privacy entries to my Info.plist

  • Modifying the code:

    • lowered the update interval

    • checking for returned errors from the closure

    • running it on a different thread

  • Searched online for example projects, StackOverflow, etc., but without luck

  • Run the code as an iPhone app. Here it works as expected without issues.

I'm fairly new to this forum and Apple Development, so any help would be much appreciated!

Hello Gabriel,

I struggle with what appears the same issue. Did you find the solution in the meantime?

Hello Gabriel,

I struggle with what appears the same issue. Did you find the solution in the meantime?

Hi, I ran into the same issue on a Series 4 watch with watchOS 8.3 and I'm pretty sure it's an error in watchOS because the Series 4 does not have the gyro (which is required by device motion). Also, the isGyroAvailable property is false.

The documentation of isDeviceMotionAvailable even states:

The device-motion service is available if a device has both an accelerometer and a gyroscope. Because all devices have accelerometers, this property is functionally equivalent to isGyroAvailable.

.isDeviceMotionAvailable returns true, but data from .deviceMotion is always nil
 
 
Q