Search code examples
swift3ios10core-motion

selecting attitude reference frame in IOS 10 coremotion using swift 3


I am trying to use CMMotionManager to update the attitude of a camera viewpoint in scenekit. I am able to get the following code using the default reference to work.

manager.deviceMotionUpdateInterval = 0.01
manager.startDeviceMotionUpdates(to: motionQueue, withHandler:{ deviceManager, error in
                if (deviceManager?.attitude) != nil {
                    let rotation = deviceManager?.attitude.quaternion

                    OperationQueue.main.addOperation {
                        self.cameraNode.rotation = SCNVector4(rotation!.x,rotation!.y,rotation!.z,rotation!.w)
                    }
                }

        })

I am however unable to get startDeviceMotionUpdates to work with a selected reference frame as shown below:

manager.deviceMotionUpdateInterval = 0.01
manager.startDeviceMotionUpdates(using: CMAttitudeReferenceFrameXMagneticNorthZVertical, to: motionQueue, withHandler:{ deviceManager, error in
            if (deviceManager?.attitude) != nil {
                let rotation = deviceManager?.attitude.quaternion

                OperationQueue.main.addOperation {
                    self.cameraNode.rotation = SCNVector4(rotation!.x,rotation!.y,rotation!.z,rotation!.w)
                }
            }

        })

The error i receive is:

Use of unresolved identifier 'CMAttitudeReferenceFrameXMagneticNorthZVertical'

I get similar error messages for other reference frames as well. Can anyone shed any light on the use of the "using:" parameter for the startDeviceMotionUpdates function? All the examples i have found are for older versions of swift or objective c so it is quite possible that it is simply an issue with not understanding Swift 3 syntax.


Solution

  • After some additional fiddling i figured out that the using argument expects a member of the new CMAttitudeReferenceFrame struct. i.e. it should be passed as:

    manager.deviceMotionUpdateInterval = 0.01
    manager.startDeviceMotionUpdates(using: CMAttitudeReferenceFrame.xMagneticNorthZVertical
                ,to: motionQueue, withHandler:{
                deviceManager, error in
                if (deviceManager?.attitude) != nil {
                    let rotation = deviceManager?.attitude.quaternion
    
                    OperationQueue.main.addOperation {
                        self.cameraNode.rotation = SCNVector4(rotation!.x,rotation!.y,rotation!.z,rotation!.w)
                    }
                }
    
            })
    

    This is a change from earlier version that allowed the direct use of constants such as "CMAttitudeReferenceFrameXMagneticNorthZVertical"