I’m engaged on an iOS app the place I must detect when a person begins and stops driving utilizing the Apple Core Movement framework. I’ve applied the next MotionActivityManager class to deal with exercise updates and show the detected states in a SwiftUI view.
Whereas I can precisely detect “Stationary” and “Strolling” states, detecting the “Driving” (Automotive) state has been unreliable. The accuracy usually fails, and the framework ceaselessly misclassifies driving as different states like “Unknown” or “Strolling.”
Here is the implementation:
import SwiftUI
import CoreMotion
class MotionActivityManager: ObservableObject {
personal let motionActivityManager = CMMotionActivityManager()
personal let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
return formatter
}()
@Revealed var motionStates: [MotionState] = []
@Revealed var startDate: String = ""
@Revealed var confidence: String = ""
init() {
setupDefaultStates()
startActivityUpdates()
}
personal func setupDefaultStates() {
motionStates = [
MotionState(label: "Stationary", value: false),
MotionState(label: "Walking", value: false),
MotionState(label: "Running", value: false),
MotionState(label: "Automotive", value: false),
MotionState(label: "Cycling", value: false),
MotionState(label: "Unknown", value: false)
]
}
func startActivityUpdates() {
guard CMMotionActivityManager.isActivityAvailable() else {
print("Movement exercise shouldn't be out there.")
return
}
motionActivityManager.startActivityUpdates(to: .principal) { [weak self] movement in
guard let self = self, let movement = movement else { return }
DispatchQueue.principal.async {
self.updateProperties(with: movement)
}
}
}
personal func updateProperties(with movement: CMMotionActivity) {
motionStates = [
MotionState(label: "Stationary", value: motion.stationary),
MotionState(label: "Walking", value: motion.walking),
MotionState(label: "Running", value: motion.running),
MotionState(label: "Automotive", value: motion.automotive),
MotionState(label: "Cycling", value: motion.cycling),
MotionState(label: "Unknown", value: motion.unknown)
]
startDate = dateFormatter.string(from: movement.startDate)
swap movement.confidence {
case .low:
confidence = "Low"
case .medium:
confidence = "Medium"
case .excessive:
confidence = "Excessive"
@unknown default:
confidence = "Unknown"
}
}
}
struct MotionState: Identifiable {
let id = UUID()
let label: String
let worth: Bool
}
struct ContentView: View {
@StateObject personal var motionManager = MotionActivityManager()
var physique: some View {
ScrollView {
VStack(spacing: 16) {
ForEach(motionManager.motionStates) { state in
LabelView(label: state.label, worth: state.worth ? "True" : "False")
}
LabelView(label: "Confidence", worth: motionManager.confidence)
}
.padding()
}
.onAppear {
UIApplication.shared.isIdleTimerDisabled = true
motionManager.startActivityUpdates()
}
.navigationTitle("Movement Exercise")
}
}
Points:
The movement.automotive state is usually not detected precisely.
The arrogance stage stays low for the automotive state, even when the gadget is clearly in a automotive.
How can I enhance the detection accuracy of the “Driving” state utilizing the Core Movement framework?