У вас есть пара проблем с вашим кодом.
Ваша первая проблема заключается в том, что вам нужна связь между данными модели и вашим представлением. При создании привязки представление будет обновляться автоматически, когда модельизменения.
Вторая проблема заключается в том, что вы получаете доступ к данным магнитометра только один раз через motionManager.magnetometerData
, а не настраиваете закрытие для мониторинга обновлений через startMagnetometerUpdates(to:withHandler:)
.
Вы можете использовать ObservableObject
из Combine
framework и @ObservedObject
, по вашему мнению, для создания соответствующей привязки.
Начните с создания класса для переноса вашего менеджера движений:
import Foundation
import Combine
import CoreMotion
class MotionManager: ObservableObject {
private var motionManager: CMMotionManager
@Published
var x: Double = 0.0
@Published
var y: Double = 0.0
@Published
var z: Double = 0.0
init() {
self.motionManager = CMMotionManager()
self.motionManager.magnetometerUpdateInterval = 1/60
self.motionManager.startMagnetometerUpdates(to: .main) { (magnetometerData, error) in
guard error == nil else {
print(error!)
return
}
if let magnetData = magnetometerData {
self.x = magnetData.magneticField.x
self.y = magnetData.magneticField.y
self.z = magnetData.magneticField.z
}
}
}
}
Этот класс соответствуетObservableObject
и @Publish
его три свойства, x, y и z.
Простое присвоение новых значений этим свойствам в закрытии обновления магнитометра приведет к тому, что издатель запустит и обновит любые наблюдатели.
Теперь, по вашему мнению, вы можете объявить @ObservedObject
для вашего класса менеджера движения и связать свойства.
struct ContentView: View {
@ObservedObject
var motion: MotionManager
var body: some View {
VStack {
Text("Magnetometer Data")
Text("X: \(motion.x)")
Text("Y: \(motion.y)")
Text("Z: \(motion.z)")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(motion: MotionManager())
}
}
Обратите внимание, что вам нужно будет передать inпозиция MotionManager
в вашем SceneDelegate.swift
файле:
let contentView = ContentView(motion: MotionManager())