admin管理员组

文章数量:1122846

I am working on an iOS app where I need to detect when a user starts and stops driving using the Apple Core Motion framework. I've implemented the following MotionActivityManager class to handle activity updates and display the detected states in a SwiftUI view.

While I can accurately detect "Stationary" and "Walking" states, detecting the "Driving" (Automotive) state has been unreliable. The accuracy often fails, and the framework frequently misclassifies driving as other states like "Unknown" or "Walking."

Here's the implementation:

import SwiftUI
import CoreMotion

class MotionActivityManager: ObservableObject {
    private let motionActivityManager = CMMotionActivityManager()
    private let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return formatter
    }()

    @Published var motionStates: [MotionState] = []
    @Published var startDate: String = ""
    @Published var confidence: String = ""

    init() {
        setupDefaultStates()
        startActivityUpdates()
    }

    private 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("Motion activity is not available.")
            return
        }

        motionActivityManager.startActivityUpdates(to: .main) { [weak self] motion in
            guard let self = self, let motion = motion else { return }
            DispatchQueue.main.async {
                self.updateProperties(with: motion)
            }
        }
    }

    private func updateProperties(with motion: 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: motion.startDate)

        switch motion.confidence {
        case .low:
            confidence = "Low"
        case .medium:
            confidence = "Medium"
        case .high:
            confidence = "High"
        @unknown default:
            confidence = "Unknown"
        }
    }
}

struct MotionState: Identifiable {
    let id = UUID()
    let label: String
    let value: Bool
}

struct ContentView: View {
    @StateObject private var motionManager = MotionActivityManager()

    var body: some View {
        ScrollView {
            VStack(spacing: 16) {
                ForEach(motionManager.motionStates) { state in
                    LabelView(label: state.label, value: state.value ? "True" : "False")
                }
                LabelView(label: "Confidence", value: motionManager.confidence)
            }
            .padding()
        }
        .onAppear {
            UIApplication.shared.isIdleTimerDisabled = true
            motionManager.startActivityUpdates()
        }
        .navigationTitle("Motion Activity")
    }
}

Issues:

The motion.automotive state is often not detected accurately. The confidence level remains low for the automotive state, even when the device is clearly in a car.

How can I improve the detection accuracy of the "Driving" state using the Core Motion framework?

本文标签: iosDetecting Driving State with Core Motion FrameworkAutomotive Accuracy IssuesStack Overflow