My app is dependent on how the iPhone is held. For many reasons, I need to use the device sensors with CoreMotion and the .attitude property. Reading the device's attitude is only used for a few times/seconds when the user will set the configuration for my app.
I have tried both pulling and pushing the motion data. In both cases, I can't figure out how to store the CMAttitude values in a way that lets me access them elsewhere.
In the code below…
- The
printstatements inside themanager.startDeviceMotionUpdatesclosure work fine. - But … I have ZERO access to the
.attitudevalues outside the closure. - The Xcode preview crashes, as well as the app running on my device, if I try to include a
TextViewwith the attitude data.
Here is my code…
import SwiftUI
import CoreMotion
let manager = CMMotionManager()
let queue = OperationQueue()
struct ContentView: View {
@State var myAttitude: CMAttitude = CMAttitude()
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
Button(action: {
guard manager.isDeviceMotionAvailable else { return }
manager.startDeviceMotionUpdates(to: queue) { (motion, error) in
guard let motion else {
return
}
let currentAttitude = motion.attitude
myAttitude = currentAttitude
print("")
print("Attitude-Pitch: \(myAttitude)")// ←←← These Work Fine!
print("Attitude-Pitch: \(myAttitude.pitch.formatted(.number.precision(.fractionLength(5))))")
print("Attitude-Yaw: \(myAttitude.yaw.formatted(.number.precision(.fractionLength(5))))")
print("Attitude-Roll: \(myAttitude.roll.formatted(.number.precision(.fractionLength(5))))")
print("")
}
}, label: {
Text("Check Your Attitude")
.foregroundStyle(.cyan)
})
Text("Attitude-Pitch: \(myAttitude)") // ←←← App Crashes Here!
// Text("Attitude-Pitch: \(myAttitude.pitch.formatted(.number.precision(.fractionLength(5))))")
// Text("Attitude-Yaw: \(myAttitude.yaw.formatted(.number.precision(.fractionLength(5))))")
// Text("Attitude-Roll: \(myAttitude.roll.formatted(.number.precision(.fractionLength(5))))")
}
.padding()
}
}
#Preview {
ContentView(myAttitude: CMAttitude())
}
nilas a defaultand update the states in the main queue: